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

作者:慕色丶 时间:2021-06-20 04:06:35 

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://blog.csdn.net/qq_42974140/article/details/113183565

标签:Spring,@Validation,@Valid
0
投稿

猜你喜欢

  • Springboot如何操作redis数据

    2022-05-30 21:36:41
  • Java reservedcodecachesize虚拟机参数案例详解

    2022-03-15 12:18:48
  • Java 使用poi把数据库中数据导入Excel的解决方法

    2022-09-19 14:18:52
  • Android 使用 SharedPreferences 保存少量数据的实现代码

    2023-07-03 01:00:11
  • Java中后台线程实例解析

    2022-01-05 06:45:08
  • flutter日期选择器 flutter时间选择器

    2023-09-22 04:50:15
  • maven如何打包动态环境变量(包括启动脚本)

    2023-07-16 03:48:56
  • 浅谈Java后台对JSON格式的处理操作

    2023-02-16 07:28:36
  • Java结构型设计模式中建造者模式示例详解

    2023-04-24 13:37:31
  • Maven 错误找不到符号的解决方法

    2021-07-19 09:03:02
  • 深入分析java并发编程中volatile的实现原理

    2023-11-23 05:02:25
  • ClassLoader类加载源码解析

    2023-11-25 18:17:09
  • java设计模式--原型模式详解

    2023-11-25 05:08:24
  • Java之SpringBoot自定义配置与整合Druid

    2022-09-28 06:23:06
  • 浅谈java中String StringBuffer StringBuilder的区别

    2023-11-29 13:34:40
  • Android游戏开发学习之引擎用法实例详解

    2023-09-26 16:01:57
  • Spring定时任务使用及如何使用邮件监控服务器

    2023-01-12 16:38:58
  • Java实现上传文件图片到指定服务器目录

    2023-06-28 00:23:32
  • 详解Java中的线程池

    2023-11-10 16:33:27
  • Springboot导出文件,前端下载文件方式

    2023-07-21 11:27:05
  • asp之家 软件编程 m.aspxhome.com