Spring的@Validation和javax包下的@Valid区别以及⾃定义校验注解
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.ssage}"; //可以在配置⽂件中配置⾃定的消息提醒
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] vals() default { };
}
注意:可以在resources下⾯创建ValidationMessages.properties⽂件,读取⾃定义的提⽰消息
pers.ssage=参数提交错误
2)、编写⼀个⾃定义的校验器ConstraintValidator
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> t = new HashSet<>();
//初始化⽅法
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
t.add(val);
}
}
/**
*
* @param value 需要校验的值
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
ains(value);
}
}
3)、关联⾃定义的校验器和⾃定义的校验注解
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class【可以指定多个不同的校验器适配不同类型的校验】 })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {}
到此这篇关于Spring的@Validation和javax包下的@Valid区别以及⾃定义校验注解的⽂章就介绍到这了,更多相关Spring的@Validation和@Valid区别内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!