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

 更新时间:2021年01月28日 11:10:28   作者:慕色丶  
这篇文章主要介绍了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.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 {}

到此这篇关于Spring的@Validation和javax包下的@Valid区别以及自定义校验注解的文章就介绍到这了,更多相关Spring的@Validation和@Valid区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot jpa实现优雅处理isDelete的默认值

    springboot jpa实现优雅处理isDelete的默认值

    如果多个实体类都有 isDelete 字段,并且你希望在插入时为它们统一设置默认值时改怎么做呢,本文为大家整理了一些方法,希望对大家有所帮助
    2024-11-11
  • Java多线程并发JUC包ReentrantLock显示锁的用法

    Java多线程并发JUC包ReentrantLock显示锁的用法

    这篇文章主要介绍了Java多线程并发JUC包ReentrantLock显示锁的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • SpringBoot项目优雅的全局异常处理方式(全网最新)

    SpringBoot项目优雅的全局异常处理方式(全网最新)

    这篇文章主要介绍了SpringBoot项目优雅的全局异常处理方式(全网最新),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • java中使用logger打印日志有哪些坑

    java中使用logger打印日志有哪些坑

    在Java中使用日志记录器(Logger)打印日志时,确实存在一些常见的坑需要注意,本文就来介绍一下几种方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • Mybatis-Plus根据时间段去查询数据的实现示例

    Mybatis-Plus根据时间段去查询数据的实现示例

    这篇文章主要介绍了Mybatis-Plus根据时间段去查询数据的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Spring Validation方法实现原理分析

    Spring Validation方法实现原理分析

    这篇文章主要介绍了Spring Validation实现原理分析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • javaweb实现文件上传示例代码

    javaweb实现文件上传示例代码

    这篇文章主要为大家详细介绍了javaweb实现文件上传的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Java多线程之定时器Timer的实现

    Java多线程之定时器Timer的实现

    这篇文章主要为大家详细介绍了Java多线程中定时器Timer类的使用以及模拟实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • spring的事务传播属性REQUIRED_NESTED原理

    spring的事务传播属性REQUIRED_NESTED原理

    这篇文章主要介绍了spring的事务传播属性REQUIRED_NESTED原理,在spring中,要想使用事务中的回滚点,可以使用传播属性NESTED,需要的朋友可以参考下
    2023-05-05
  • 学习Java的static与final关键字

    学习Java的static与final关键字

    本篇文章给大家详细分析了Java的static与final关键字知识点以及相关代码分享,有需要的读者跟着学习下吧。
    2018-03-03

最新评论