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区别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot集成validation校验参数遇到的坑

    公众号中分享了一篇文章,关于SpringBoot集成validation校验参数的,粉丝留言说有坑. 原留言如下: 有坑,你试试^A-\\d{12}-\\d{4}$,这条正则经过validate这个方法无论参数写的对不对都会报验证错误,而用main方法测试是正常的.. 话说,针对这种回复我是不太信了,直觉告诉我,肯定是这位粉丝用错了.但既然粉丝有疑问还是需要专门写一个demo来验证一下的.说写就写. SpringBoot集成validation 集成过程非常简单,在原项目的pom文件中直接引入如

  • spring boot validation参数校验实例分析

    本文实例讲述了spring boot validation参数校验.分享给大家供大家参考,具体如下: 对于任何一个应用而言在客户端做的数据有效性验证都不是安全有效的,这时候就要求我们在开发的时候在服务端也对数据的有效性进行验证. Spring Boot自身对数据在服务端的校验有一个比较好的支持,它能将我们提交到服务端的数据按照我们事先的约定进行数据有效性验证. 1 pom依赖 <dependency> <groupId>org.springframework.boot</gr

  • SpringMVC实现Validation校验过程详解

    这篇文章主要介绍了SpringMVC实现Validation校验过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.概述 对前端的校验大多数通过js在页面校验,这种方法比较简单,如果对安全性考虑,还要在后台校验. springmvc使用JSR-303(javaEE6规范的一部分)校验规范,springmvc使用的是Hibernate Validator(和Hibernate的ORM) 二.步骤 2.1 引入 Hibernate Vali

  • 如何使用Spring Validation优雅地校验参数

    引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(UserVO userVO) { if(userVO.getAge() == null){ return "年龄不能为空"; } if(userVO.getAge() > 120){ return "年龄不能超过120"; } if(userVO.getName().isEmpty()){ return &q

  • Spring-Validation 后端数据校验的实现

    前言 最近看到很多童鞋在项目中的对请求参数的校验都用的if来判断各参数的属性,如: if(StringUtils.isBlank(username)){ return RR.exception("账号不能为空"); } if(StringUtils.isBlank(password)){ return RR.exception("密码不能为空"); } if(StringUtils.isBlank(realName)){ return RR.exception(&q

  • springMVC引入Validation的具体步骤详解

    本文简单介绍如何引入validation的步骤,如何通过自定义validation减少代码量,提高生产力.特别提及:非基本类型属性的valid,GET方法的处理,validation错误信息的统一resolve. 本文中validation的实际实现委托给Hibernate validation处理 基本配置 pom引入maven依赖 <!-- validation begin --> <dependency> <groupId>javax.validation<

  • Spring Validation方法实现原理分析

    最近要做动态数据的提交处理,即需要分析提交数据字段定义信息后才能明确对应的具体字段类型,进而做数据类型转换和字段有效性校验,然后做业务处理后提交数据库,自己开发一套校验逻辑的话周期太长,因此分析了Spring Validation的实现原理,复用了其底层花样繁多的Validator,在此将分析Spring Validation原理的过程记录下,不深入细节 如何使用Spring Validation Spring Bean初始化时校验Bean是否符合JSR-303规范 1.手动添加BeanVali

  • 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; 在检验Contr

  • javax.validation自定义日期范围校验注解操作

    实际项目中经常需要对传入的日期时间进行判断,如是否为一年内,几个月之内,几天前,几天之内等等的需求. 如要求前端传入的日期是要为当前日期一年内的某个日期,基于jdk8的LocalDateTime or LocalDate等常用的做法如下: // 前端传字符串如'2020-07-13 09:09:09' springmvc接收并转换为LocalDateTime类型 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd

  • spring配置扫描多个包问题解析

    spring 配置扫描多个包,有时候我们希望不同功能类型的包放在不同的包下,这就需要 <!-- 自动扫描该包,使 SpringMVC 为包下用了@controller注解的类是控制器 --> <context:component-scan base-package="com.weixiao.ssmcleardb.controller" /> <context:component-scan base-package="com.weixiao.lis

  • Spring boot validation校验方法实例

    前言 接触springboot一年多,是时候摆脱这种校验方式了233 ,每个参数都if判断,一眼看过去就是很low的程序员. Validation有了这个插件就再也不用这样去校验参数了,可以让我们在项目中不用浪费很多时间在参数校验这里,从而更专注于业务逻辑 正文 首先引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web

  • Spring自动扫描无法扫描jar包中bean的解决方法

    发现问题 前几天用eclipse打包了一个jar包,jar包里面是定义的Spring的bean. 然后将jar包放到lib下,设置spring的自动扫描这个jar包中的bean,可谁知根本无法扫描到bean,显示错误就是找不到bean,当时就纳闷儿了,为什么扫描不到,结果搜索之后才发现,用eclipse打包jar包要勾选"Add directory entries"才能被Spring正确扫描到,居然有这个说法,呵呵- 不知道 勾选"Add directory entries&

  • spring boot打包成war包的页面如何存放

    背景 经常有朋友问我,平时都是使用spring mvc,打包成war包发布到tomcat上,如何快速到切换到spring boot的war或者jar包上? 先来看看传统的war包样式是什么样子的? 1. 传统的spring MVC格式的war包 可以看到,webapp/resouces文件存放css/js/html等静态文件,WEB-INF存放jsp动态文件. 对应的配置文件 @EnableWebMvc //mvc:annotation-driven @Configuration @Compon

  • Spring 使用Validation 验证框架的问题详解

    一.介绍 Spring Validation 验证框架对参数的验证机制提供了@Validated (Spring's JSR-303 规范,是标准 JSR-303 的一个变种),javax 提供了@Valid(标准 JSR-303 规范),配合 BindingResult 可以直接提供参数验证结果.其中对于字段的特定验证注解,比如 @NotNull. 两者在检验 Controller 的入参是否符合规范时,使用@Validated 或者 @Valid 在基本验证功能上没有太多区别.但是在分组.注

  • SpringBoot中的Condition包下常用条件依赖注解案例介绍

    目录 一.@ConditionalOnClass() Spring中存在指定class对象时,注入指定配置 1.首先引入pom依赖 2.实体类测试对象 3.定义@ConditionalOnClass()配置类 4.启动类测试 二.注入指定配置 1.首先引入pom依赖 2.实体类测试对象 3.定义@ConditionalOnMissingClass()配置类 4.启动类测试 三.加载指定配置 1.首先引入pom依赖 2.实体类测试对象 2.1 引入条件判断实体类 3.定义@ConditionalO

  • Java语言Lang包下常用的工具类介绍

    无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都很不错,不用你写,不用你调试,只要你发现. 在 Apache Jakarta Common 中, Lang 这个 Java 工具包是所有 Apache Jakarta Common 项目中被使用最广泛的,几乎你所知道的名气比较大的软件里面都有用到它,包括 Tomcat, Weblogic, Websphere, Eclipse 等等.我们就从这个包开始介绍整个 common 项

随机推荐