《SpringBoot篇》12.@Valid与@Validated的区别

简介: 《SpringBoot篇》12.@Valid与@Validated的区别

1.介绍


说明: 其实@Valid 与 @Validated都是做数据校验的,只不过注解位置与用法有点不同。


不同点:

(1)

@Valid是使用Hibernate validation的时候使用。@Validated是只用Spring Validator校验机制使用。


(2)

@Valid 可以嵌套验证

@Validation 不能进行嵌套验证


(3)

@Valid:可以用在方法、构造函数、方法参数和成员属性(field)上。

@Validated:用在类、方法和方法参数上。但不能用于成员属性(field)。

(如果@Validated注解在成员属性上,则会报不适用于field的错误。)


(4)

@Valid:没有分组功能。

@Validated:提供分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制。


2.用法


(1)@Valid用法

a.导入依赖

SpringBoot项目:


<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>

b.使用前提是实体类中属性使用注解进行校验

package com.example.demo.pojo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
//lombok
@Data
public class User implements Serializable {
    //用户名
    @NotBlank(message = "请输入名称")
    @Length(message = "名称不能超过个 {max} 字符", max = 10)
    private String username;
    //年龄
    @NotNull(message = "请输入年龄")
    @Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100)
    private String age;
}

c.在Controller方法参数中加上@Valid注解

package com.example.demo.controller;
import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class UserController {
    public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());
    @PostMapping("/add")
    @ResponseBody
    public String add(@Validated User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
            return "添加失败";
        }
        return "添加成功";
    }
}

经过测试填写错误数据,会在控制台输出报错信息。


image.png


(2)@Validated用法

a.开启校验框架(与上面一样)

<!--1.导入JSR303规范-->

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>
<!--使用hibernate框架提供的校验器做实现-->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

c.在需要开启校验功能的类上使用注解@Validated开启校验功能,对具体的字段设置校验规则,这里讲的是可以在类上使用@Validated注解,配合xml数据绑定。

@Component
@Data
@ConfigurationProperties(prefix = "servers")
//开启对当前bean的属性注入校验
@Validated
public class ServerConfig {
    //设置具体的规则
    @Max(value = 8888,message = "最大值不能超过8888")
    @Min(value = 202,message = "最小值不能低于202")
    private int port;
}

(3)@Validated实现分组校验

注意 分组校验就是把条件加入组中,可以自由选择开启那些组的校验方式。


a.分组接口

package com.example.demo.pojo;
public interface Group {
    interface Update{};
    interface FindAll{};
}


b.实体类

package com.example.demo.pojo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
//lombok
@Data
public class User implements Serializable {
    //用户名
    @NotBlank(message = "请输入用户名不能为空",groups = {Group.FindAll.class})
    @Length(message = "名称不能超过个 {max} 字符", max = 10 ,groups = {Group.FindAll.class})
    private String username;
    //年龄
    @NotBlank(message = "请输入年龄不能为空",groups = {Group.Update.class})
    @Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100,groups = {Group.Update.class})
    private String age;
}

c.controller接口:

注意 @Validated有参数 value中写分组名称


package com.example.demo.controller;
import com.example.demo.pojo.Group;
import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class UserController {
    public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());
    @PostMapping("/add")
    @ResponseBody
    //注意@Validated有参数 value中写分组名称
    public String add(@Validated(value = {Group.Update.class}) User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
            return "添加失败";
        }
        return "添加成功";
    }
}


(4)@Valid 实现嵌套校验

注: 嵌套检测就是在一个User类中,存在另外一个User2类的属性。嵌套检测User同时也检测User2。


a.实体类User

package com.example.demo.pojo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
//lombok
@Data
public class User implements Serializable {
    //用户名
    @NotBlank(message = "请输入用户名不能为空1")
    private String username;
    //年龄
    @NotBlank(message = "请输入年龄不能为空1")
    private String age;
    @Valid
    @NotNull(message = "user2不能为空1")
    private User2 user2;
}
}


b.实体类User2

package com.example.demo.pojo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
package com.example.demo.pojo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
//lombok
@Data
public class User2 implements Serializable {
    //用户名
    @Length(message = "名称不能超过个 {max} 字符2", max = 10 )
    private String username2;
    //年龄
    @Range(message = "年龄范围为 {min} 到 {max} 之间2", min = 1, max = 100)
    private String age2;
}


c.Controller类(这里使用@Valid)

package com.example.demo.controller;
import com.example.demo.pojo.Group;
import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class UserController {
    public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());
    @PostMapping("/add")
    @ResponseBody
    public String add(@Valid User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
            return "添加失败";
        }
        return "添加成功";
    }
}


相关文章
|
Java API 数据安全/隐私保护
掌握Spring Boot中的@Validated注解
【4月更文挑战第23天】在 Spring Boot 开发中,@Validated 注解是用于开启和利用 Spring 的验证框架的一种方式,特别是在处理控制层的输入验证时。本篇技术博客将详细介绍 @Validated 注解的概念和使用方法,并通过实际的应用示例来展示如何在项目中实现有效的数据验证
719 3
|
前端开发 安全 Java
SpringBoot验证框架@Valid
SpringBoot验证框架@Valid
151 1
|
Java Spring
springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
858 7
|
XML 前端开发 Java
SpringBoot参数校验@Validated、@Valid(javax.validation)详解
SpringBoot参数校验@Validated、@Valid(javax.validation)
2292 4
|
JSON Java 数据格式
springboot全局异常实现以及@Valid和@Validated优雅实现入参验证
springboot全局异常实现以及@Valid和@Validated优雅实现入参验证
1357 0
|
前端开发 Java Spring
【Spring Boot 快速入门】十四、Spring Boot集成@Valid注解的接口参数合法性校验
【Spring Boot 快速入门】十四、Spring Boot集成@Valid注解的接口参数合法性校验
719 0
|
15天前
|
JavaScript Java 关系型数据库
基于springboot的项目管理系统
本文探讨项目管理系统在现代企业中的应用与实现,分析其研究背景、意义及现状,阐述基于SSM、Java、MySQL和Vue等技术构建系统的关键方法,展现其在提升管理效率、协同水平与风险管控方面的价值。
|
6天前
|
JavaScript 安全 Java
基于springboot的宠物领养系统
本系统基于Spring Boot、Java、Vue与MySQL技术,构建高效、安全的宠物领养平台,实现信息集中管理、智能匹配与数据保护,提升领养效率,推动“以领养代替购买”的文明理念。
|
17天前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
16天前
|
JavaScript Java 关系型数据库
基于springboot的古树名木保护管理系统
本研究针对古树保护面临的严峻挑战,构建基于Java、Vue、MySQL与Spring Boot技术的信息化管理系统,实现古树资源的动态监测、数据管理与科学保护,推动生态、文化与经济可持续发展。