1.后臺引數校驗
Spring Validation驗證框架對引數的驗證機制提供了@Validated(Spring JSR-303規范,是標準JSR-303的一個變種),javax提供了@Valid(標準JSR-303規范),配合BindingResult可以直接提供引數驗證結果
spring提供的驗證:org.springframework.validation.annotation.Validated;
javax提供的驗證:javax.validation.Valid;
在檢驗Controller的入參是否符合規范時,使用@Validated或者@Valid在基本驗證功能上沒有太多區別,但是在分組、注解地方、嵌套驗證等功能上兩個有所不同:
1.1 分組
@Validated:提供了一個分組功能,可以在入參驗證時,根據不同的分組采用不同的驗證機制,這個網上也有資料,不詳述,
@Valid:作為標準JSR-303規范,還沒有分組的功能,
1.2 注解地方
@Validated:可以用在型別、方法和方法引數上,但是不能用在成員屬性(欄位)上
@Valid:可以用在方法、建構式、方法引數和成員屬性(欄位)上
兩者是否能用于成員屬性(欄位)上直接影響能否提供嵌套驗證的功能,
1.3 嵌套驗證
@Validated:用在方法入參上無法單獨提供嵌套驗證功能,不能用在成員屬性(欄位)上,也無法提示框架進行嵌套驗證,能配合嵌套驗證注解@Valid進行嵌套驗證,
示例代碼:
#使用@Validated的分組功能,需要提供介面,原因是
@Target({ElementType.TYPE, ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
Class<?>[] value() default {}; #需要定義型別做區分,所以提供個介面做分組區分
}
示例分類介面:
public interface CreateGroup {
}
#在需要驗證的欄位上添加分組即可
示例代碼:
public class WebOrderQo {
/**
* 用戶ID
*/
@ApiModelProperty("用戶ID")
@NotNull(message = "用戶ID不能為空", groups = {UpdateGroup.class, CreateGroup.class, QueryGroup.class})
private Long uid;
}
#在Controller里面的方法上加@Validated注解,啟動分組需要在@Validated(CreateGroup.class)填上對應的分組型別,默認沒有指定分組的校驗注解@NotNull,在分組校驗情況@Validated({CreateGroup.class})下不生效,只會在@Validated生效;
示例代碼:
@RestController
public class ItemController {
@RequestMapping("/item/add")
public void addItem(@Validated Item item, BindingResult bindingResult) {
doSomething();
}
}
@Valid:用在方法入參上無法單獨提供嵌套驗證功能,能夠用在成員屬性(欄位)上,提示驗證框架進行嵌套驗證,能配合嵌套驗證注解@Valid進行嵌套驗證
示例代碼:
public class Item {
@NotNull(message = "id不能為空")
@Min(value = 1, message = "id必須為正整數")
@ListValue(vals = {0,1}) //自定義注解
private Long id;
@Valid // 嵌套驗證必須用@Valid
@NotNull(message = "props不能為空")
@Size(min = 1, message = "props至少要有一個自定義屬性") //嵌套驗證
private List<Prop> props;
}
2.自定義引數驗證注解
當驗證框架提供的驗證注解無法滿足業務需求的時候,可以自定義驗證注解實作我們的業務需求
1)、撰寫一個自定義的校驗注解
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{pers.store.market.common.valid.ListValue.message}"; //可以在組態檔中配置自定的訊息提醒
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] vals() default { };
}
注意:可以在resources下面創建ValidationMessages.properties檔案,讀取自定義的提示訊息
pers.store.market.common.valid.ListValue.message=引數提交錯誤
2)、撰寫一個自定義的校驗器ConstraintValidator
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
//初始化方法
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
/**
*
* @param value 需要校驗的值
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
3)、關聯自定義的校驗器和自定義的校驗注解
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class【可以指定多個不同的校驗器適配不同型別的校驗】 })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {}
有什么錯誤的地方,請多多指教!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/253081.html
標籤:java
