Spring参数校验

news2025/1/10 21:33:17

如何使用

Spring提供了简便的参数校验注解,不需要像以前一样if else去判断了,下面记录一下如何使用注解实现参数的校验

导入坐标

要使用各种注解完成参数的校验,需要导入hibernate-validator坐标以实现

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.1.Final</version>
        </dependency>

常用注解如下(本人并没有都使用过,粘贴的)
@Null 检查该字段为空
@NotNull 不能为null
@NotBlank 不能为空,常用于检查空字符串
@NotEmpty 不能为空,多用于检测list是否size是0
@Max 该字段的值只能小于或等于该值
@Min 该字段的值只能大于或等于该值
@Past 检查该字段的日期是在过去
@Future 检查该字段的日期是否是属于将来的日期
@Email 检查是否是一个有效的email地址
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
@Size(min=, max=) 检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等
@Length(min=,max=) 检查所属的字段的长度是否在min和max之间,只能用于字符串
@AssertTrue 用于boolean字段,该字段只能为true
@AssertFalse 该字段的值只能为false

注解说明

我们使用到的验证参数注解共有两个@Valid与@Validated。
@Validated:可以用在类型、方法和方法参数上,支持分组校验。但是不能用在成员属性上,不支持嵌套检测;
@Valid:可以用在方法、构造方法、方法参数和成员属性上,支持嵌套检测。

验证注解时可能抛出的异常说明

在使用注解校验参数的过程中,可能由于参数不合法会抛出各种异常,但是大体就只有下面三种
BindException:表单提交时,如果参数未通过注解校验抛出该异常,对于以json格式提交将不会抛出该异常
MethodArgumentNotValidException:前端以JSON格式提交参数,后端使用requestBody接收时,如果参数未通过注解校验则抛出该异常。需要说明的是,该异常是BindException的子类
ConstraintViolationException :1. 接口参数上加@RequestParam、@PathVariable或者没加任何注解(按形参名赋值)
2. 接口参数加@NotBlank、@NotNull、@Length等校验注解
当1和2都成立时,也就是说当直接在接口的参数中对基本类型进行校验时,若校验未通过则抛出该异常

简单的使用

1. 创建接收参数的对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Student {
    @NotNull(groups = Group1.g12.class,message = "学号不能为空")
    @Length(min = 2,max = 3, groups = Group1.g12.class,message = "学号长度错误,需要在2~3位之间")
    private String no;

    @NotNull(groups = Group1.g11.class,message = "姓名不存在!")
    private String name;

    @Max(12)
    private Integer age;

    private String address;

}
2.创建实现分组校验的接口
public interface Group1 {
	//命名比较随意,看看就行
    public interface g11{};
    public interface g12{};
    public interface g13{};
    public interface g14{};
    
}
3.写几个接口测试测试
    @PostMapping("v1")
    public void v1(@Validated(Group1.g12.class) Student student){  //bindException
        System.out.println(student.toString());
    }

    @GetMapping("v2/{name}")
    public void v2(@PathVariable @Length(min = 2,max = 5,message = "name长度需要在2~5之间") String name){ //ConstraintViolationException
        System.out.println(name);
    }

    @PostMapping("v3")
    public void v3(@RequestBody @Validated Student student){ //MethodArgumentNotValidException
        System.out.println("业务执行了...");
        System.out.println(student.toString());
    }

可以看到,我写了三个接口,v1是验证Student(加入了分组校验),v2是直接在接口参数中对基本类型String进行校验,v3是接收JSON参数进行校验
接下来我们一个一个测试:
v1
v1接口很明显,需要对Student进行校验,并且指定了分组Group1.g12.class,而通过观察Student对象可以看到,只有学号no携带了该分组,所以只要学号字段验证通过就没问题。但是当学号为空时则控制台打印Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors<EOL>Field error in object 'student' on field 'no': rejected value [null]; codes [NotNull.student.no,NotNull.no,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.no,no]; arguments []; default message [no]]; default message [学号不能为空]<EOL>Field error in object 'student' on field 'no': rejected value [null]; codes [NotNull.student.no,NotNull.no,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.no,no]; arguments []; default message [no]]; default message [学号不能为空]]
当学号超过3位长度时则控制台打印:Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'student' on field 'no': rejected value [1200]; codes [Length.student.no,Length.no,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.no,no]; arguments []; default message [no],3,2]; default message [学号长度错误,需要在2~3位之间]]

v2(提示下,直接在接口中对基本类型进行校验需要在controller上打@Validated注解)
v2就是在接口参数中直接对对基本类型进行校验,长度需要在2~5之间,所以我们直接发送一个不符合条件的请求,http://localhost:8080/v2/HelloWorld,控制台打印:
在这里插入图片描述
v3
v3就是接收参数的形式变成了JSON,并且进行了参数校验(不带任何分组),所以只是对age进行了校验,age不能超过12,我们试着发送一个不合法的请求,JSON参数为{“name”:“zhangsan”,“age”:15},结果控制台打印:Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void com.example.validation.controller.VController.v3(com.example.validation.entity.Student): [Field error in object 'student' on field 'age': rejected value [15]; codes [Max.student.age,Max.age,Max.java.lang.Integer,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.age,age]; arguments []; default message [age],12]; default message [最大不能超过12]] ]

4.关于分组校验

分组校验的情况下,对于没有添加分组校验的注解将不会生效
没有分组校验情况下,只会校验不带分组校验的校验注解

5.分组校验的全局异常处理

在第三步中,我们测试完接口发现报出了不同的异常信息,那么全局异常处理是必不可少的,需要将不合法的提示正确的返回给用户。
经过测试,对于报出的异常共有三类

  1. 对于直接在接口中进行校验的基本类型参数(包含String),抛出ConstraintViolationException
  2. 对于JSON请求映射的参数,抛出MethodArgumentNotValidException
  3. 对于接口参数为对象时,抛出BindException

其中,MethodArgumentNotValidException是BindException的子类
那么,我们只需要拦截BindException和ConstraintViolationException进行处理即可,如下:

	//拦截BindException和MethodArgumentNotValidException
    @ExceptionHandler(BindException.class)
    public Map<String, String> MANVE(BindException e){
        Map<String, String> res = new LinkedHashMap();
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        for (ObjectError item:allErrors) {
            if (item instanceof FieldError){
                String field = ((FieldError) item).getField();
                String defaultMessage = ((FieldError) item).getDefaultMessage();
                res.put(field,defaultMessage);
            }
        }
        return res;
    }
	//拦截ConstraintViolationException
    @ExceptionHandler(ConstraintViolationException.class)
    public Map<String,String> CVE(ConstraintViolationException e){
        Map<String,String> res = new LinkedHashMap<>();
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        for (ConstraintViolation item: constraintViolations) {
            String messageTemplate = item.getMessageTemplate();
            PathImpl propertyPath = (PathImpl) item.getPropertyPath();
            NodeImpl leafNode = propertyPath.getLeafNode();
            res.put(leafNode.asString(),messageTemplate);
        }
        return res;
    }

可以把代码中的返回报错信息改为你所需要的形式

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

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

相关文章

[Spring Cloud] nacos安装与使用

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

密码学消息鉴别

信息安全 完整性 1.数据完整性&#xff1a;数据未被篡改或损坏。数据是不可否认的&#xff0c;发送方和接收方不能抵赖处理了数据。 2.系统完整性&#xff1a;系统未被非授权使用。 真实性 确认实体是它声明的&#xff0c;适用于用户、进程等等的合法的信息&#xff08;是否真…

LVS-DR模式

文章目录一、LVS-DR集群介绍1、LVS-DR 工作原理2、 数据包流向分析3、LVS-DR 模式的特点4、LVS-DR中的ARP问题4.1 问题一4.2问题二二、构建LVS-DR集群的步骤实验环境准备&#xff1a;1、配置负载调度器&#xff08;192.168.2.66&#xff09;1.1 配置虚拟 IP 地址&#xff08;VI…

HTML+CSS+JS网页设计期末课程大作业—— 艺术官网17页(包含登陆注册)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 公司官网网站 | 企业官网 | 酒店官网 | 等网站的设计与制 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 CSS&#…

力扣(LeetCode)22. 括号生成(C++)

回溯 括号合法的性质&#xff1a; 任意前缀的左括号数大于右括号数左括号和右括号的数量相等。 根据性质 &#xff0c; 写递归体 。 class Solution { public:vector<string> ans;vector<string> generateParenthesis(int n) {dfs(n,0,0,"");return …

Mosaic数据增强

paper&#xff1a;YOLOv4: Optimal Speed and Accuracy of Object Detection mosaic data augmentation最早是在YOLO v4的文章中提出的&#xff0c;但其实在ultralytics-YOLOv3中就已经实现了。具体就是将4张样本拼接成一张图&#xff0c;具有以下优点&#xff1a;&#xff08…

C++string—常用接口介绍+模拟实现+习题讲解

如果调试一个程序让你很苦恼&#xff0c;千万不要放弃&#xff0c;成功永远在拐角之后&#xff0c;除非你走到拐角&#xff0c;否则你永远不知道你离他多远&#xff0c;所以&#xff0c;请记住&#xff0c;坚持不懈&#xff0c;直到成功。 目录 前言 1.string类的常用接口 1.1s…

c++提高篇——模板(下)

c提高篇——模板&#xff08;下&#xff09;一、类模板二、类模板与函数模板区别三、类模板中成员函数创建时机四、类模板对象做函数参数一、类模板 类模板可以建立一个通用类&#xff0c;类中的成员数据类型可以不具体制定&#xff0c;用一个虚拟的类型来代表。 类模板的语法…

周赛补题

leetcode &#xff1a; 第一题https://leetcode.cn/problems/number-of-unequal-triplets-in-array/可以直接暴力 class Solution { public:int unequalTriplets(vector<int>& nums) {int sum 0;int n nums.size();for(int i 0; i < n; i ){for(int j i …

kmp算法记录

看了如何更好地理解和掌握 KMP 算法?之后&#xff0c;做的整理 相关知识 尽管普通模式匹配的时间复杂度是O(mn)&#xff0c;KMP 算法的时间复杂度是O(mn)&#xff0c;但在一般情况下&#xff0c;普通模式匹配的实际执行时间近似为O(m n)&#xff0c;因此至今仍被采用。KMP算法…

一文弄懂CNN中的BatchNorm

1. 引言 本文重点介绍BatchNorm的定义和相关特性&#xff0c;并介绍了其详细实现和具体应用。希望可以帮助大家加深对其理解。 嗯嗯&#xff0c;闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 什么是BatchNorm&#xff1f; BatchNorm是2015年提出的网络层&#xff0c…

一文讲懂高并发分布式系统,听不懂你来打我

众所周知&#xff0c;在分布式系统的设计与建立中&#xff0c;其中一个要考虑的问题就是高并发。 那么&#xff0c;到底什么是高并发呢? 简单来说高并发就是指通过设计系统&#xff0c;使之实现可以同时处理多个请求的能力。 现在的高并发系统主要存在有两种实现方式&#…

Utilizing Transformer Representations Efficiently

ContentsIntroductionDifferent Pooling StrategiesPooler OutputLast Hidden State OutputHidden States OutputMore...ReferencesIntroduction 在用预训练模型微调时&#xff0c;我们比较习惯于直接用 Transformer 最后一层的输出经过 FC / Bi-LSTM… 后输出最终结果。但实际…

Perforce P4V 资源汇总

Perforce P4V 入门https://download.csdn.net/download/love_xiaozhao/20533522 P4 Command Referencehttps://download.csdn.net/download/love_xiaozhao/20534062 P4V文件状态命令速查表https://download.csdn.net/download/love_xiaozhao/20533404PerforcexHelix分支策略_…

【android Framework 探究】android 13 aosp编译全记录

写在开始 自从关注Framework这一块儿&#xff0c;就有了自己编译aosp刷机的想法&#xff0c;模拟器当然是可以的&#xff0c;但是体验感还不能和真机想比&#xff0c;于是买一个二手piexl的想法就有了&#xff0c;根据预算选定piexl 5&#xff0c;支持最新的android 13&#xf…

编码命名方式知多少

文章目录1.camel case &#xff08;驼峰式&#xff09;2.snake case &#xff08;蛇形式&#xff09;3.kebab case &#xff08;烤串式&#xff09;4.匈牙利命名法5.小结参考文献编码时&#xff0c;命名无处不在。比如我们需要对文件命令&#xff0c;对目录命名&#xff0c;对变…

m低信噪比下GPS信号的捕获算法研究,使用matlab算法进行仿真

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 GPS系统的星座部分是由21颗工作卫星和3颗在轨备用卫星组成&#xff0c;其高度为20183km&#xff0c;这24颗卫星均匀分布在6个等间隔的、相对轨道面倾角为55的近圆轨道上。 ​ GPS卫星的…

处理csv、bmp等常用数据分析操作--python

请先看思维导图&#xff0c;看是否包含你所需要的东西&#xff0c;如果没有&#xff0c;就可以划走了&#xff0c;免得浪费时间&#xff0c;谢谢 条条大路通罗马&#xff0c;我只是介绍了我掌握的这一条&#xff0c;不喜勿喷&#xff0c;谢谢。 目录 一、创建文件夹&#xff0…

一行日志,让整个文件导出服务导出内容都为空..

输出一行日志&#xff0c;却让整个文件上传服务挂了...问题分析小结问题 直接上代码&#xff0c;看看有无眼尖的小伙伴发现问题&#xff1a; // 设置参数 MultiValueMap<String, Object> param new LinkedMultiValueMap<>(); FileSystemResource resource new …

log4cpp初入门

目录下载与安装log4cpp框架CategoryAppenderLayoutPriortyOutput功能日志级别⽇志格式化⽇志输出日志回滚日志配置文件下载与安装 https://sourceforge.net/projects/log4cpp/ tar xvf log4cpp-1.1.3.tar.gz cd log4cpp ./configure make make check make install ldconfig…