@Valid 和 @Validated 注解用法详解

@Valid 和 @Validated 注解用法详解Valid 注解通常用于对象属性字段的规则检测 具体啥意思 下面让我娓娓道来 下面我们以新增一个员工为功能切入点 以常规写法为背景 慢慢烘托出 Valid 注解用法详解 那么 首先 我们会有一个员工对象 Employee 如下 员工对象 authorsunnyz since2019 12 13 publiccl

目录

案例引入

@Valid 详解

@Validated 详解

@Valid 和 @Validated 比较


案例引入

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

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

/ * 员工对象 * * @author sunnyzyq * @since 2019/12/13 */ 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个字符,那么我们以前的做法大致如下:

@Valid 和 @Validated 注解用法详解

写完,我们启动项目测试下:

(1)名称为空情况

@Valid 和 @Validated 注解用法详解

(2)正常情况

@Valid 和 @Validated 注解用法详解

(3)超过长度情况

@Valid 和 @Validated 注解用法详解

可以看到,和我们料想中的一样,毫无问题。

除了名称外,我们规定年龄也是必填项,且范围在1到100岁,那么此时,我们需要增加对应判定代码如下:

@Valid 和 @Validated 注解用法详解

那么问题来了,现在员工对象 Employee 就 2 个字段,我们就写了 10 多行的代码验证,要是有20个字段,岂不是要写 100 多行代码?通常来说,当一个方法中的无效业务代码量过多时,往往代码设计有问题,当然这不是我们所想看到都结果。

那么如何解决呢?首先大家应该会想到将对应的验证过程抽成一个验证方法,如下:

这样来看,我们的业务方法就清爽多了。

@Valid 和 @Validated 注解用法详解

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

@Valid 详解

此时,我们引出 Spring 中的 @valid 注解,这些问题就可以迎刃而解了,具体如下:

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

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

 
    
    
      org.springframework.boot 
     
    
      spring-boot-starter-web 
     
    
      2.0.5.RELEASE 
     
   

如果你不是 springboot 项目,那么引入下面依赖即可:

 
    
    
      javax.validation 
     
    
      validation-api 
     
    
      1.1.0.Final 
     
    
    
    
      org.hibernate 
     
    
      hibernate-validator 
     
    
      5.4.1.Final 
     
   

那么针对上面情景,我们可以对我们的代码进行优化了。

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

package com.zyq.beans; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; / * 员工对象 * * @author sunnyzyq * @since 2019/12/13 */ 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 注解,表示我们对这个对象属性需要进行验证,

@Valid 和 @Validated 注解用法详解

既然验证,那么就肯定会有验证结果,所以我们需要用一个东西来存放验证结果,做法也很简单,在参数直接添加一个BindingResult,具体如下:

@Valid 和 @Validated 注解用法详解

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

@Valid 和 @Validated 注解用法详解

OK ! 万事俱备 !我们进行测试下:

(1)名称为空

@Valid 和 @Validated 注解用法详解

(2)名称正常,年龄为空

@Valid 和 @Validated 注解用法详解

(3)名称超出范围,年龄正常

@Valid 和 @Validated 注解用法详解

(4)名称正常,年龄超出范围

@Valid 和 @Validated 注解用法详解

可以看到,代码不但简洁了很多,结果和预期的也一模一样!很棒吧!!

常用注解:

除了刚刚都注解,最后再附加2个常用注解,我就直接贴图了,基本上这6个注解可以解决99%的字段,其他注解我就不贴图了,如果不满足,自己问百度。

@Valid 和 @Validated 注解用法详解

@Validated 详解

上面,我们讲述了 @Valid 注解,现在我们来说说 @Validated 这个注解,在我看来,@Validated 是在 @Valid 基础上,做的一个升级版。

我们可以看到,我们在使用 @Valid 进行验证的时候,我们需要用一个对象去接收校验结果,最后根据校验结果判断,从而提示用户。

@Valid 和 @Validated 注解用法详解

如果我们把手动校验的这段代码删除或注释掉,那么即使当我们的字段不满足规则时,方法种的程序也是能够被执行的。

比如,我们将字段值置空时,正常情况是会进行提示的。

@Valid 和 @Validated 注解用法详解

 当我们把校验逻辑注释掉后,再次执行上面的请求后。

@Valid 和 @Validated 注解用法详解

可以看到我们的程序继续往后面去执行完成了。 

@Valid 和 @Validated 注解用法详解

现在,我们去掉方法参数上的 @Valid 注解和其配对的 BindingResult 对象,

然后再校验的对象前面添加上 @Validated 注解。

@Valid 和 @Validated 注解用法详解

这个时候,我们再次请求,可以看到,我们请求报400错误了。

@Valid 和 @Validated 注解用法详解

而我们通过程序的异常日志来看,提示说是 age 和 name 字段为了空,致使请求失败。

@Valid 和 @Validated 注解用法详解

那么,从这里我们可以得知,当我们的数据存在校验不通过的时候,程序就会抛出

org.springframework.validation.BindException 的异常。

在实际开发的过程中,我们肯定不能讲异常直接展示给用户,而是给能看懂的提示。

于是,我们不妨可以通过捕获异常的方式,将该异常进行捕获。

首先我们创建一个校验异常捕获类 ValidExceptionHandler ,然后打上 @RestControllerAdvice 注解,该注解表示他会去抓所有 @Controller 标记类的异常,并在异常处理后返回以 JSON 或字符串的格式响应前端。

@Valid 和 @Validated 注解用法详解

算了,我直接将这段代码贴出来吧。

在异常捕捉到后,我们同上面的 @valid 校验一样,只返回第一个错误提示。

package com.zyq.config; import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class ValidExceptionHandler { @ExceptionHandler(BindException.class) public String validExceptionHandler(BindException exception) { return exception.getAllErrors().get(0).getDefaultMessage(); } }

那么,我们现在重启程序,然后重新请求,就可以发现界面已经不报400错误了,而是直接提示了我们的错误信息。

@Valid 和 @Validated 注解用法详解

@Valid 和 @Validated 比较

最后我们来对 @Valid 和 @Validated 两个注解进行总结下:

(1)@Valid 和 @Validated 两者都可以对数据进行校验,待校验字段上打的规则注解(@NotNull, @NotEmpty等)都可以对 @Valid 和 @Validated 生效;

(2)@Valid 进行校验的时候,需要用 BindingResult 来做一个校验结果接收。当校验不通过的时候,如果手动不 return ,则并不会阻止程序的执行;

(3)@Validated 进行校验的时候,当校验不通过的时候,程序会抛出400异常,阻止方法中的代码执行,这时需要再写一个全局校验异常捕获处理类,然后返回校验提示。

(4)总体来说,@Validated 使用起来要比 @Valid 方便一些,它可以帮我们节省一定的代码,并且使得方法看上去更加的简洁。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201046.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午10:03
下一篇 2026年3月20日 上午10:03


相关推荐

  • HTML的dpr

    HTML的dpr只是为了自己以后查找方便 看不懂勿怪 DPI PPI 屏幕像素密度或屏幕每英寸的像素数量 dips 手机尺寸或独立像素物理像素 手机分辨率 dpr nbsp window devicePixelR js 可以拿到 css 定义 psd 转换 rem 单位 rem px 基准值基准值 手机宽高 dpr 10 乘以 dpr 是因为页面有可能缩放除以 10 是为了取整

    2025年9月22日
    6
  • 腾讯“龙虾”(OpenClaw/本地虾)对绿联科技是明确利好,且是强催化。一、先

    腾讯“龙虾”(OpenClaw/本地虾)对绿联科技是明确利好,且是强催化。一、先

    2026年3月15日
    2
  • 大物电磁感应定律知识总结_电动势等于电压吗

    大物电磁感应定律知识总结_电动势等于电压吗动生电动势:磁场保持不变,导体回路或导体在磁场中运动产生的电动势感生电动势:导体回路不动,磁场发生变化产生的电动势一、在磁场中运动的导线内的感应电动势磁通量变化率为:根据法拉第电磁感应定律,在运动导线MN段上产生的动生电动势即为:因此,动生电动势在量值上等于在单位时间内导线所切割的磁感应线数动生电动势的电子理论解释当导线以速度v向右运动时,导线内每个自由电子获得向右的定向速度v,由于在磁场中,自由电子收到洛伦兹力电子在这个力的作用下,从导…

    2025年7月26日
    5
  • centos6 7 zabix grafana安装配置

    centos6 7 zabix grafana安装配置一 安装 zabbix0 关闭 selinuxvim etc selinux configSELINU disabled 设置后需要重启才能生效 shell gt setenforce0 临时关闭 shell gt getenforce 检测 selinux 状态 1 Zabbix 在 CentOS 基本源里不可获得或者获得到的都是老版本的 因此必须配置 Zabbix 官方 r

    2025年7月30日
    7
  • 高并发解决方案相关面试题

    高并发解决方案相关面试题什么是DNS解析域名DNS域名解析就是讲域名转化为不需要显示端口(二级域名的端口一般为80)的IP地址,域名解析的一般先去本地环境的host文件读取配置,解析成对应的IP地址,根据IP地址访问对应的服务器。若host文件未配置,则会去网络运营商获取对应的IP地址和域名.什么是NginxNginx是一个高级的轻量级的web服…

    2022年5月22日
    35
  • j2me开发环境搭建[通俗易懂]

    j2me开发环境搭建[通俗易懂]学习j2me的开发也有半年了,很多东西需要记住并不断实践。 j2me的环境搭建过程。 要准备的东东:1.JDK;2.开发工具Eclipse;3.eclipseMe;4.WTK;   一、下载jdk,并安装,安装好后配置环境变量,假设现在jdk的安装目录是E:/ProgramFiles/Java/jdk1.6.0_10,那么按如下配置环境变量:

    2022年7月11日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号