@Valid与@Validated的区别

news2024/9/20 20:25:01

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 "添加成功";
    }
}

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

=

(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 "添加成功";
    }
}

总结:

了解这两个注解可以让你的校验数据更加方便。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/358135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql里的ibtmp1文件太大,导致磁盘空间被占满

目录 一、查看磁盘的时候发现磁盘空间100% 二、 排查的时候&#xff1a;查看是什么文件占用的时候&#xff0c;发现是数据库临时表空间增长的 三、为了避免以后再次出现ibtmp1文件暴涨&#xff0c;限制其大小&#xff0c;需在配置文件加入 四、重启Mysql实例&#xff08;重启后…

6 大经典机器学习数据集,3w+ 用户票选得出,建议收藏

内容一览&#xff1a;本期汇总了超神经下载排名众多的 6 个数据集&#xff0c;涵盖图像识别、机器翻译、遥感影像等领域。这些数据集质量高、数据量大&#xff0c;经历人气认证值得收藏码住。 关键词&#xff1a;数据集 机器翻译 机器视觉 数据集是机器学习模型训练的基础&…

【电商】OMS--零售电商系统的核心

本文讲述了OMS概念以及相关服务和功能&#xff08;包括&#xff1a;信息下发、信息上传、 订单分发协同单号生成与拉、拆单发票服务、状态更新与模板、流水、库存&#xff09; OMS即&#xff1a;订单管理中心&#xff0c;是零售电商系统的核心。 随着中台概念的火热&#xff0…

graphsage解读

传统的图方法都是直推式(transductive)的&#xff0c;学习到的是结构固定的图模型&#xff0c;一旦有新的节点加入&#xff0c;便需要重新训练整个图网络&#xff0c;泛化性不强。GraphSAGE是归纳式(inductive)的&#xff0c;它学习一种映射&#xff1a;通过采样和聚合邻居节点…

ModStartBlog v6.7.0 后台管理优化,页面宽度调整

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装会…

二叉树OJ(二)二叉树中和为某一值的路径 I、II、III

二叉树中和为某一值的路径(一) 描述 给定一个二叉树root和一个值 sum &#xff0c;判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。 1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点 2.叶子节点是指没有子节点的节点 3.路径只能从父节点到子节点&…

对JS文件中每个函数单独混淆加密

自动化脚本&#xff1a;单独对JS代码中的每个函数进行混淆加密 用自动化脚本工具&#xff0c;对JS代码中的每个函数分别进行单独混淆加密。这样加密得到的JS代码&#xff0c;比直接对整个JS代码进行混淆加密&#xff0c;效果要好很多。所谓“好”体现在&#xff1a;加密结果安…

Interspeech2022 | 一种基于元辅助学习的低资源口语语义理解方法

中国移动研究院首席科学家冯俊兰博士带领人工智能与智慧运营中心语音团队共同撰写的文章《Meta Auxiliary Learning for Low-resource Spoken Language Understanding》被语音国际顶会Interspeech2022接收。 关于Interspeech Interspeech 是国际最大且最全面关于言语科学与技…

QT for Android BLE Bluetooch QT BLE

小白式的介绍&#xff0c;很详细了&#xff0c;很多主要内容写在程序的注释里&#xff0c;慢慢看 下面是我的源码 https://download.csdn.net/download/qq_27620407/87464307 源码打不开的话可以试试下图的操作&#xff0c;之后电机确定&#xff0c;可能是加图标搞的&#xff0…

自监督表征预训练之掩码图像建模

自监督表征预训练之掩码图像建模 前言 目前&#xff0c;在计算机视觉领域&#xff0c;自监督表征预训练有两个主流方向&#xff0c;分别是对比学习&#xff08;contrastive learning&#xff09;和掩码图像建模&#xff08;masked image modeling&#xff09;。两个方向在近几…

CLEVE:事件抽取的对比预训练

CLEVE: Contrastive Pre-training for Event Extraction 论文&#xff1a;CLEVE: Contrastive Pre-training for Event Extraction (arxiv.org) 代码&#xff1a;THU-KEG/CLEVE: Source code for ACL 2021 paper “CLEVE: Contrastive Pre-training for Event Extraction” (g…

初探Upgrade内存马(内存马系列篇六)

写在前面 前面讲解了一个特殊的Tomcat内存马-Executor内存马&#xff0c;这篇同样是一个特殊&#xff0c;可以不被检测到的内存马-Upgrade内存马。 这篇就是内存马系列文章的第六篇了。 前置 在阅读这篇文章之前&#xff0c;同样需要对Tomcat的架构&#xff0c;和初始化流程…

秒懂算法 | 莫队算法

01、基础莫队算法 莫队算法 = 离线 + 暴力 + 分块。 “离线”和“在线”的概念。在线是交互式的,一问一答;如果前面的答案用于后面的提问,称为“强制在线”。离线是非交互的,一次性读取所有问题,然后一起回答,"记录所有步,回头再做”。 基础的莫队算法是一种离线…

[Java安全]—Shiro回显内存马注入

文章目录前言流程分析寻找response流程分析获取Http11Processor获取AbstractProtocol获取Connector获取WebappClassLoaderHeader 长度限制绕过1、反射修改maxHeaderSize2、自定义ClassLoader加载Body数据后记参考前言 接上篇[Java安全]—Tomcat反序列化注入回显内存马_&#x…

【基于混合激活残差块:超分】

SRNHARB: A deep light-weight image super resolution network using hybrid activation residual blocks &#xff08;SRNHARB&#xff1a;一种基于混合激活残差块的深度轻量图像超分辨率网络&#xff09; 在所有基于图像的应用中&#xff0c;特别是在计算机视觉应用中&…

软件测试期末

考原题就是爽 软件测试技术 知识点整理 https://wenku.baidu.com/view/524c900f4b2fb4daa58da0116c175f0e7cd11913.html 关键知识点 https://www.cnblogs.com/whylaughing/category/813559.html?page1 边界值法不选择无效数据 边界值分析法的基本思想 选取正好等于&am…

PageObject设计模式,在selenium自动化测试中的运用

PageObject设计模式 Web自动化测试框架&#xff08;WebTestFramework&#xff09;是基于Selenium框架且采用PageObject设计模式进行二次开发形成的框架。web测试时,建议强烈推荐使用_谷歌或_火狐浏览器。PageObject设计模式&#xff1a;是将某个页面的所有"元素&#xff…

【网络原理3】TCP连接管理

TCP这种传输层协议必须是有连接的。连接管理&#xff0c;就是TCP当中管理如何建立连接、如何断开连接的方式。 目录 TCP建立连接的方式(三次握手) 合并两次连接之后变成"三次握手" 站在具体发送什么报文的视角&#xff0c;理解三次握手 发送报文之前 第一步:客…

Git - 在主分支上创建分支并提交代码

拉取最新代码 因为当前在 master 分支下&#xff0c;你必须拉取最新代码&#xff0c;保证当前代码与线上同步&#xff08;最新&#xff09;&#xff0c;执行以下命令&#xff1a; git pull origin master创建分支 目前我们在 master 主分支上&#xff0c;需要执行以下命令&…

【Unity】[入门tips与通用性原则] 一些经验技巧和更好地写出简洁易懂的程序的原则方法

本文将持续间断更新 本文主要面向初级程序员&#xff0c;为了方便Unity开发&#xff0c;有些快捷键的方式和一些通用性的技巧tips等会在这篇博客内持续更新&#xff0c;欢迎点赞收藏 快捷键 Ctrl S &#xff1b; 快捷保存&#xff01;闲着没事就来两下&#xff01;CtrlShif…