Spring的@Validation和javax包下的@Valid区别以及自定义校验注解

网友投稿 211 2023-02-06

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 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 {

private Set set = new HashSet<>()vAGfArtC;

//初始化方法

@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 {}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:springboot基于Redis发布订阅集群下WebSocket的解决方案
下一篇:springBoot接入阿里云oss的实现步骤
相关文章

 发表评论

暂时没有评论,来抢沙发吧~