spring boot中使用Bean Validation做优雅的参数校验
一、Bean Validation简介
Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),目前最新稳定版2.0.2(201909)
对于spring boot应用,直接引用它提供的starter
<!-- 基于注解的数据校验规范 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
二、常用注解
常用注解如下:

直接在Controller层使用
@RestController
@RequestMapping("/app/api")
@Validated
@Slf4j
public class SpringGuaranteeReportController {@RequestMapping("/sendSpringGuaranteeReport")public ResultObject<String> sendSpringGuaranteeReport(@Min(value = 1) @Max(value = 2) Integer mmsType,@Min(value = 1) @Max(value = 2) Integer groupType,@NotBlank String opTime) {…………}
}
一个简单的接口,传入一个Person对象,加上@Valid启用校验,bindingResult里面就包含了参数校验的结果
@Data
public class Person {@NotBlank(message = "姓名不能为空")private String name;@NotBlank(message = "性别不能为空")private String sex;@NotNull(message = "年龄不能为空")@Max(value = 100, message = "年龄不能超过100")private Integer age;@Email(message = "电子邮箱格式错误")private String email;@Pattern(regexp = "^1[3|4|5|7|8][0-9]{9}$")private String phone;@NotEmpty(message = "兴趣不能为空")private List<String> hobby;
}
这里做了判空和基本格式校验
其中关于@NotEmpty、@NotNull、@NotBlank的区别:
简单来说,在Integer或者自定义对象中使用@NotNull,在String上使用@NotBlank,在集合上使用NotEmpty
三、配置类
validate参数校验默认的是一个参数校验失败后,还会继续校验后面的参数,通过这个配置改成:校验参数时只要出现校验失败的情况,就立即抛出对应的异常,结束校验,不再进行后续的校验
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;/*** validate参数校验默认的是一个参数校验失败后,还会继续校验后面的参数* 通过这个配置改成:校验参数时只要出现校验失败的情况,就立即抛出对应的异常,结束校验,不再进行后续的校验*/
@Configuration
public class ValidationConfig {@Beanpublic Validator validator() {ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()/**failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验*/.failFast(true).buildValidatorFactory();return validatorFactory.getValidator();}@Beanpublic MethodValidationPostProcessor methodValidationPostProcessor() {MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();methodValidationPostProcessor.setValidator(validator());return methodValidationPostProcessor;}}
validate参数校验失败后,返回的json数据可能并不是咱们最终想要的,下图就是校验失败后它默认返回的数据

一般情况下,咱们可能只需要图中标红的那个提示信息就OK了
那怎么改它的返回数据呢?
只要添加一个异常处理类就行了,捕获抛出的异常
import com.ai.boy.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;/*** 全局异常处理*/
@ControllerAdvice
@Slf4j
public class GlobalHandlerExceptionResolver {/*** 处理请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常*/@ExceptionHandler(BindException.class)@ResponseBodypublic R BindExceptionHandler(BindException e) {String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());return R.error(message);}/*** 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException*/@ExceptionHandler(ConstraintViolationException.class)@ResponseBodypublic R ConstraintViolationExceptionHandler(ConstraintViolationException e) {String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());return R.error(message);}/*** 处理未知异常* */@ExceptionHandler(Exception.class)@ResponseBodypublic R error(HttpServletResponse response, Exception e){log.info("未知异常信息:{}",e.getMessage());return R.error("未知异常,请联系管理员!");}}
相关文章:
spring boot中使用Bean Validation做优雅的参数校验
一、Bean Validation简介 Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),目前最新稳定版2.0.2(201…...
搜索引擎项目
认识搜索引擎 1、有一个主页、有搜索框。在搜索框中输入的内容 称为“查询词” 2、还有搜索结果页,包含了若干条搜索结果 3、针对每一个搜索结果,都会包含查询词或者查询词的一部分或者和查询词具有一定的相关性 4、每个搜索结果包含好几个部分&…...
7.外部存储器,Cache,虚拟存储器
目录 一. 外部存储器 (1)磁盘存储器 1.磁盘的组成 2.磁盘的性能指标 3.磁盘地址 4.硬盘的工作过程 5.磁盘阵列 (2)固态硬盘(SSD) 二. Cache基本概念与原理 三. Cache和主存的映射方式 ÿ…...
UITableView的style是UITableViewStyleGrouped
一般情况下,UITableViewStylePlain和UITableViewStyleGrouped是UITableView常用到的style, 之前都是用到的时候,遇到问题直接用度娘,差不多就够用了,今天在修复UI提出的间隙问题,来回改,总觉得…...
Java17新增特性
前言 前面的文章,我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍,对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…...
VR全景技术在城市园区发展中有哪些应用与帮助
引言: 在数字化时代的浪潮中,虚拟现实(VR)全景技术逐渐融入各个领域,也为城市园区展示带来了全新的可能性。 一.VR全景技术简介 虚拟现实全景技术是一种通过全景图像和视频模拟真实环境的技术。通过相关设…...
在 SQL 中,当复合主键成为外键时应该如何被其它表引用
文章目录 当研究一个问题慢慢深入时,一个看起来简单的问题也暗藏玄机。在 SQL 中,主键成为外键这是一个很平常的问题,乍一看没啥值得注意的。但如果这个主键是一种复合主键,而另一个表又引用这个键作为它的复合主键,问…...
Ps:通过显示大小了解图像的打印尺寸
在 Photoshop 中,如果想了解文档窗口中的图像打印出来之后的实质大小,只要知道两个数值即可。 第一个数值是图像分辨率(也称“文档分辨率”)的大小,可在Ps菜单:图像/图像大小 Image Size对话框中查询或设置…...
Linux - 驱动开发 - watchdog - SMP机制下多核确活
说明 理论上:不管IC是单核还是多核,只要watchdog有被循环feed,就不会触发超时重启,因此watchdog在SMP机制下的多核环境显得比较宽松,只要任意核存活(喂狗)就不会重启设备。 实际情况 有客户反…...
概念解析 | LoRA:低秩矩阵分解在神经网络微调中的魔力
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:基于低秩矩阵分解的神经网络微调方法LoRA LoRA:低秩矩阵分解在神经网络微调中的魔力 Low-Rank Adaptation of Large Language Models LoRA由如下论文提出,详细信息请参见论文原…...
量子计算和量子通信技术:引领潜力无限的未来
近年来,随着量子计算和量子通信技术的迅速发展,它们在各个领域的广泛应用前景引起了人们的极大兴趣。本文将深入探讨量子计算和量子通信技术的普遍应用,以及它们预示的未来,同时提出业内人士需要注意的事项。 介绍:量子…...
nodejs+vue+python+PHP+微信小程序-安卓- 电影在线订票系统的设计与实现-计算机毕业设计推荐
目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…...
LightDB23.4支持mysql aes_encrypt/aes_decrypt/hex/unhex函数
背景介绍 为了兼容mysql数据库的功能,在LightDB23.4版本上支持hex/unhex/aes_encrypt/aes_decrypt函数。 函数原型如下: hex(data bytea) returns textunhex(data varchar) returns byteaaes_encrypt(data bytea, key bytea) returns byteaaes_encryp…...
uniapp——项目day04
购物车页面——商品列表区域 渲染购物车商品列表的标题区域 1. 定义如下的 UI 结构: 2.美化样式 渲染商品列表区域的基本结构 1. 通过 mapState 辅助函数,将 Store 中的 cart 数组映射到当前页面中使用: import badgeMix from /mixins/tab…...
7-爬虫-中间件和下载中间件(加代理,加请求头,加cookie)、scrapy集成selenium、源码去重规则(布隆过滤器)、分布式爬虫
0 持久化(pipelines.py)使用步骤 1 爬虫中间件和下载中间件 1.1 爬虫中间件(一般不用) 1.2 下载中间件(代理,加请求头,加cookie) 1.2.1 加请求头(加到请求对象中) 1.2.2 加cookie 1.2.3 加代理 2 scrapy集成selenium 3 源码去重…...
创建自己的nas服务,从远端拉取所需文件
一、前言 创建一个nas文件存储,然后需要的时候随时从远端或者其他终端拉取所需文件是不是一件很帅气的工作。 二、准备工作 一台服务器(云的更好),没了。 首先安装docker和docker-compose 此处省略docker的安装(改天更新)&…...
智慧化城市内涝的预警,万宾科技内涝积水监测仪
随着城市化进程的加速,伴随的是城市内涝问题日益凸显。频繁的暴雨和积水给市民的生活带来了诸多不便,也给城市的基础设施带来了巨大压力。如何解决这一问题,成为智慧城市建设的重要课题和政府管理的工作主题,只要内涝问题得到缓解…...
7-18 调用一个函数
分数 2 作者 Yiping 单位 广东东软学院 现有如下程序,请将注释后带??的代码补充完整: import mathdef normalize(normal):x normal[0]y normal[1]z normal[2]s math.sqrt(x**2 y**2 z**2)x / sy / sz / sreturn (x, y, z)if __name__ __mai…...
VB.net TCP服务端监听端口接收客户端RFID网络读卡器上传的读卡数据
本 示例使用设备介绍:WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) Imports System.Threading Imports System.Net Imports System.Net.Sockets Public Class Form1Dim ListenSocket As SocketDim Dict As New Dictionary(Of…...
Springboot 集成 MongoDB
在SpringBoot项目中集成MongoDB后的一些基本操作。 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 本文介绍的内容是Springboot如何集成MongoDB,以及对MongoDB进行基本的增加、查询数据的操作。 提示:以下是本篇…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
