参数校验Spring的@Valid注解用法解析

 更新时间:2021年08月04日 15:36:54   作者:JavaEdge.  
这篇文章主要介绍了参数校验Spring的@Valid注解用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

参数校验Spring的@Valid注解

@Valid 注解通常用于对象属性字段的规则检测。

以新增一个员工为功能切入点,以常规写法为背景,慢慢烘托出 @Valid 注解用法详解。

那么,首先,我们会有一个员工对象 Employee,如下 :

public class Employee { 
    /** 姓名 */
    public String name;
 
    /** 年龄 */
    public Integer age;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    } 
}

然后 Cotroller 中会有一个对应都新增方法 add():

@Controller
public class TestController { 
    @RequestMapping("/add")
    @ResponseBody
    public String add(Employee employee) {
        // TODO 保存到数据库
        return "新增员工成功";
    } 
}

需求变更,要求员工名称不能为空,且长度不超过10个字符

我们的原始写法:

现在规定年龄也是必填项,且范围在1到100岁,那么此时,我们需要增加判定

现在员工对象 Employee 就 2 个字段,我们就写了 10 多行的代码验证,要是有20个字段,岂不是要写 100 多行代码?

如何解决呢?

将验证过程抽成一个验证方法:

但这种方式只是抽了一个方法,有一种换汤不换药的感觉,虽然业务方法看起来清爽了很多,但书写代码量并没有下降,反而还多出了一个方法。

此时引出 Spring 的 @valid 注解即可:

首先,我们在 Maven 配置中引入 @valid 的依赖:

如果你是 springboot 项目,那么可以不用引入了,已经引入了,他就存在于最核心的 web 开发包里面。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.0.5.RELEASE</version>
</dependency>

代码优化

首先在 Employee 类的属性上打上如下注解:

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; 
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
public class Employee {
 
    /** 姓名 */
    @NotBlank(message = "请输入名称")
    @Length(message = "名称不能超过个 {max} 字符", max = 10)
    public String name;
 
    /** 年龄 */
    @NotNull(message = "请输入年龄")
    @Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100)
    public Integer age;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    } 
}

然后再 Controller 对应方法上,对这个员工标上 @Valid 注解,表示我们对这个对象属性需要进行验证

用一个东西来存放验证结果,做法也很简单,在参数直接添加一个BindingResult:

对应获取验证结果的代码如下:

@Valid与@Validated注解

之前项目中参数的校验,都是自己写的判断方法进行校验,这次采用了spring提供的注解进行参数的校验,更为的方便,简洁。

@Valid:常见用在方法,类中字段上进行校验

@Validated:是spring提供的对@Valid的封装,常见用在方法上进行校验

定义的校验类型

@Null 验证对象是否为null

@NotNull 验证对象是否不为null, 无法查检长度为0的字符串

@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.

@NotEmpty 检查约束元素是否为NULL或者是EMPTY.

@CreditCardNumber信用卡验证

@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。

@URL(protocol=,host=, port=,regexp=, flags=) ip地址校验

Booelan检查

@AssertTrue 验证 Boolean 对象是否为 true

@AssertFalse 验证 Boolean 对象是否为 false

长度检查

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内

@Length(min=, max=) Validates that the annotated string is between min and max included.

日期检查

@Past 验证 Date 和 Calendar 对象是否在当前时间之前

@Future 验证 Date 和 Calendar 对象是否在当前时间之后

@Pattern 验证 String 对象是否符合正则表达式的规则

数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为""时无法转换为int,但可以转换为Stirng为"",Integer为null

@Min 验证 Number 和 String 对象是否大等于指定的值

@Max 验证 Number 和 String 对象是否小等于指定的值

@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度

@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度

@Digits 验证 Number 和 String 的构成是否合法

@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。

@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.

注意的几点:

(1)如果一个bean中包含第二个bean

这时要检验第二个bean中某个字段,即嵌套校验,必须要在第一个bean对象中使用@Valid标注到表示第二个bean对象的字段上,然后再第二个bean对象里面的字段上加上校验类型

(2)@Validated支持分组注解

1、先定义一个空接口:GroupA

2、对bean对象中校验类型,添加分组信息,这里我对version字段进行了分组校验信息添加

3、方法入参中进行分组信息添加

如上图所示,则shelveProject方法由于添加了分组信息会校验DeleteProjectRequest对象中的version字段是否为空,而offShelveProject方法没有添加分组信息,不会校验version是否为空。

@Validated没有添加groups属性时,默认验证没有分组的验证属性。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java 中的 String对象为什么是不可变的

    Java 中的 String对象为什么是不可变的

    String对象是不可变的,但这仅意味着你无法通过调用它的公有方法来改变它的值。本文给大家介绍java中的string对象为什么是不可变的,需要的朋友一起了解了解吧
    2015-10-10
  • java中线程的sleep()方法和yield()方法的区别

    java中线程的sleep()方法和yield()方法的区别

    本文主要介绍了java中线程的sleep()方法和yield()方法的区别,Thread类的sleep()方法使线程休眠指定时间,不释放锁,而yield()提示调度器当前线程愿意让出CPU资源,不保证立即切换线程,感兴趣的可以了解一下
    2024-10-10
  • SpringBoot实现获取客户端IP地理位置

    SpringBoot实现获取客户端IP地理位置

    在当今互联的世界中,了解客户端的地理位置对于提供个性化服务和增强用户体验至关重要,使用本文为大家介绍了SpringBoot获取客户端IP地理位置的相关方法,需要的小伙伴可以参考下
    2023-11-11
  • hadoop之MapReduce框架原理

    hadoop之MapReduce框架原理

    这篇文章主要介绍了hadoop的MapReduce框架原理,MapReduce是分为两个阶段的,MapperTask阶段,和ReduceTask阶段。如果有感兴趣的小伙伴可以借鉴参考
    2023-03-03
  • Java 按照字节来截取字符串的代码(不会出现半个汉字)

    Java 按照字节来截取字符串的代码(不会出现半个汉字)

    Java 按照字节来截取字符串的工具,不会出现半个汉字。一个中文两个字节,一个英文字符只占 1 个字节** 1. 通常我们用于前端显示的时候,防止标题过长
    2014-01-01
  • java如何根据时间戳生成有序ID

    java如何根据时间戳生成有序ID

    这篇文章主要介绍了java如何根据时间戳生成有序ID问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • spring本地事务失效的原因分析

    spring本地事务失效的原因分析

    这篇文章给大家介绍了spring本地事务失效的情况原因分析,给大家罗列了五种原因分析,通过代码示例介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2023-10-10
  • 在Springboot中Mybatis与Mybatis-plus的区别详解

    在Springboot中Mybatis与Mybatis-plus的区别详解

    MyBatis是一个优秀的持久层框架,它对JDBC的操作数据库的过程进行封装,MyBatisPlus (简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生,本文将给大家介绍了在Springboot中Mybatis与Mybatis-plus的区别
    2023-12-12
  • Java SpringBoot自定义starter详解

    Java SpringBoot自定义starter详解

    大家好,本篇文章主要讲的是Java SpringBoot自定义starter详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次
    2022-01-01
  • 基于JavaBean编辑器读取peroperties文件的实例

    基于JavaBean编辑器读取peroperties文件的实例

    下面小编就为大家带来一篇基于JavaBean编辑器读取peroperties文件的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10

最新评论