优雅的入参校验,Valid常用校验

更好的阅读体验:优雅的入参校验,Valid常用校验


对于前端传递的参数,正常情况下后端是要进行一些必要的校验,最简单的做法是用 if

效果是可以,但不优雅。使用 @Validator 代替 if,就会优雅很多


ps:Validator 也可用于Dubbo参数校验


一、效果展示


如Post请求需要一个name参数,当name参数不传递的时候

在这里插入图片描述


二、引入 Validator


2-1、pom 文件引入

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><scope>compile</scope>
</dependency>

本质上引入的是

<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><scope>compile</scope>
</dependency>

2-2、全局异常处理器


校验不通过会抛出异常,所以需要一个异常处理器来做提示语处理

对全局异常拦截器感兴趣的看这里 @ControllerAdvice异常拦截原理解析

import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;@ControllerAdvice
@RestController
public class AllControllerAdvice {public final static Logger logger = LoggerFactory.getLogger(AllControllerAdvice.class);@ResponseStatus(HttpStatus.OK)@ExceptionHandler(IllegalArgumentException.class)public String illegalArgumentHandler(IllegalArgumentException e) {logger.error("IllegalArgumentException-error->", e);return e.getMessage();}@ResponseStatus(HttpStatus.OK)@ExceptionHandler(MethodArgumentNotValidException.class)public String handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {logger.error("MethodArgumentNotValidException->", e);return this.getErrorMessages(e.getBindingResult());}@ResponseStatus(HttpStatus.OK)@ExceptionHandler(BindException.class)public String handleBindException(BindException e) {logger.error("BindException error->", e);return String.format("xxxxxx" + ":%s", this.getBindingErrorField(e.getBindingResult()));}@ResponseStatus(HttpStatus.OK)@ExceptionHandler(InvalidFormatException.class)public String handleInvalidFormatException(InvalidFormatException e) {logger.error("InvalidFormatException error->", e);return e.getMessage();}@ResponseStatus(HttpStatus.OK)@ExceptionHandler(ConstraintViolationException.class)public String handleConstraintViolationException(ConstraintViolationException e) {logger.error("ConstraintViolationException-error->", e);return e.getConstraintViolations().stream().map(this::getMessage).collect(Collectors.joining(";"));}@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ExceptionHandler(Exception.class)public String exceptionHandler(Exception e) {logger.error("Exception-error->", e);return "UNKNOWN_ERROR_MESSAGE";}private String getBindingErrorField(BindingResult bindingResult) {return bindingResult.getAllErrors().stream().map(this::getFieldName).collect(Collectors.joining(";"));}private String getErrorMessages(BindingResult bindingResult) {return bindingResult.getAllErrors().stream().map(this::getMessage).collect(Collectors.joining(";"));}private String getMessage(ObjectError error) {if (error instanceof FieldError) {FieldError fieldError = (FieldError) error;return fieldError.getField() + ":" + fieldError.getDefaultMessage();}return error.getObjectName() + ":" + error.getDefaultMessage();}private String getFieldName(ObjectError error) {if (error instanceof FieldError) {FieldError fieldError = (FieldError) error;return fieldError.getField();}return error.getObjectName();}private String getMessage(ConstraintViolation<?> violation) {return violation.getPropertyPath() + ":" + violation.getMessage();}
}

如果在Dubbo中使用,那就需要定义一个Filter,这个Filter就用来充当全局异常处理器


2-3、Controller


Controller

import com.xdx97.cli.pojo.entity.ValidQuery;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/cli")
public class CliController {@PostMapping(value = "/valid")public String valid(@RequestBody @Validated ValidQuery validQuery) {System.out.println(validQuery);return "success";}
}

ValidQuery

import lombok.Data;
import lombok.ToString;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.*;@Data
@ToString
public class ValidQuery {@NotBlank(message = "不能为空")@Length(min = 1, max = 5, message = "长度必须在[1,5]之间")private String name;
}

注:@Data@ToString 是 lombok 提供了,用来省略get、set、toString方法,和校验无关


三、常用校验


已经知道如何使用参数校验,下面再来看看常用的校验有哪些,只需要把对应的校验复制到 ValidQuery 就可以验证了


3-1、基础校验


字符串

@NotBlank(message = "不能为空")
@Length(min = 1, max = 5, message = "长度必须在[1,5]之间")
@Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "用户名只能包含字母、数字和下划线")
private String name;

数字

Integer、Long 都适用

@NotNull(message = "不能为空")
@Max(value = 100, message = "最大为100")
@Min(value = 1, message = "最小为1")
private Integer age;

小数

BigDecimal、Double、Float 都适用

@NotNull(message = "不能为空")
@DecimalMax(value = "100.00", message = "最大为100.00")
@DecimalMin(value = "1.00", message = "最小为1.00")
@Digits(integer = 3, fraction = 2, message = "金额整数位最多3位,小数位最多2位")
private BigDecimal amount;

集合

List、Set、Map 都适用

@NotEmpty(message = "列表不能为空")
@Size(min = 1, max = 5, message = "列表长度必须在1到5之间")
private List<Integer> statuses;

时间/日期

@NotNull(message = "日期不能为空")
@Past(message = "日期必须是过去的时间")
@Future(message = "日期必须是未来的时间")
private LocalDate date;

3-2、嵌套校验


对象里面嵌套集合对象

@Data
@ToString
public class ValidQuery {@NotEmpty(message = "列表不能为空")@Validprivate List<ValidQueryChild> items;@Data@ToStringstatic class ValidQueryChild {@NotBlank(message = "不能为空")@Length(min = 1, max = 5, message = "长度必须在[1,5]之间")private String childName;}
}

参数是集合对象且对象里面嵌套集合对象

ValidQuery 还是和上面一样,但Controller要改变

  1. 把 @Validated 移到Controller上
  2. 入参添加 @Valid和 @NotEmpty
@RestController
@RequestMapping("/cli")
@Validated
public class CliController {@PostMapping(value = "/valid")public String valid(@RequestBody @NotEmpty(message = "列表不能为空") @Valid List<ValidQuery> validQueries) {System.out.println(validQueries);return "success";}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重学SpringBoot3-Spring Data JPA简介

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-Spring Data JPA简介 1. 什么是 Spring Data JPA&#xff1f;2. Spring Data JPA 的核心概念2.1. 实体&#xff08;Entity&#xff09;2.2. Repository&…

SpringBoot整合mybatisPlus实现批量插入并获取ID

背景&#xff1a;需要实现批量插入并且得到插入后的ID。 使用for循环进行insert这里就不说了&#xff0c;在海量数据下其性能是最慢的。数据量小的情况下&#xff0c;没什么区别。 【1】saveBatch(一万条数据总耗时&#xff1a;2478ms) mybatisplus扩展包提供的&#xff1a;…

吴恩达深度学习(9)

经典的神经网络&#xff1a; 残差网络&#xff08;ResNet&#xff09; 太深的神经网络容易出现梯度消失与梯度爆炸等问题。 跳跃连接&#xff0c;能从一层中得到激活并将其传递给下一层&#xff0c;甚至更深的网络层。利用这个可以训练网络层很深很深的残差网络&#xff08;R…

Go 1.19.4 命令调用、日志、包管理、反射-Day 17

1. 系统命令调用 所谓的命令调用&#xff0c;就是通过os&#xff0c;找到系统中编译好的可执行文件&#xff0c;然后加载到内存中&#xff0c;变成进程。 1.1 exec.LookPath&#xff08;寻找命令&#xff09; 作用&#xff1a; exec.LookPath 函数用于在系统的环境变量中搜索可…

海思hi3536c配置内核支持USB摄像头

linux内核版本&#xff1a;linux-3.18.20 配置步骤 进入Device Drivers 选择Multimedia support&#xff0c;并进入 选择Media USB Adapters&#xff0c;并进入 如下图&#xff0c;选择这几项&#xff1a; 保存退出&#xff0c;重新编译内核下载 内核更新后&#xff0c…

DIFFEDIT: DIFFUSION-BASED SEMANTIC IMAGE EDIT- ING WITH MASK GUIDANCE

https://arxiv.org/pdf/2210.11427 问题引入 针对的问题是输入text prompt完成对图片的编辑&#xff0c;基于的是T2I model&#xff1b;本文的方法不需要额外提供mask来将任务变为inpaint任务&#xff0c;而是可以自动的根据text prompt来提取出需要编辑区域的mask methods

支付域——支付背景

摘要 支付体系作为现代金融的重要组成部分,承担着资金流转与经济交易的关键职能。随着科技的发展,全球支付方式迅速演变,尤其是在中国,移动支付、互联网支付等新兴方式已广泛应用。传统的现金、银行卡支付逐渐被数字支付所取代,支付宝、微信支付等第三方支付机构成为主流…

计算机网络:数据链路层 —— 扩展共享式以太网

文章目录 共享式以太网共享式以太网存在的问题在物理层扩展以太网扩展站点与集线器之间的距离扩展共享式以太网的覆盖范围和站点数量 在链路层扩展以太网网桥的主要结构网桥的基本工作原理透明网桥自学习和转发帧生成树协议STP 共享式以太网 共享式以太网是当今局域网中广泛采…

Leetcode|24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 面试题 02.07. 链表相交 ● 142.环形链表II

24. 注意&#xff1a;涉及头节点的修改或者删除时&#xff0c;最好设置一个虚拟的头结点&#xff0c;方便简化代码&#xff0c;不必进行是否为头节点的的判断&#xff0c;简化code class Solution { public:ListNode* swapPairs(ListNode* head) {ListNode* dummyHead new Li…

Adobe Acrobat DC 打印PDF文件,没有打印出注释的解决方法

adobe acrobat在打印的时候&#xff0c;打印不出来注释内容&#xff08;之前一直可以&#xff0c;突然就不行&#xff09;&#xff0c;升级版本、嵌入字体等等都试过&#xff0c;也在Google找了半天和问了GPT也么找着办法。 无奈之下&#xff0c;自己通过印前检查&#xff0c;…

ASP.NET Core8.0学习笔记(二十一)——EFCore关系配置API

一、关系配置API概述 当我们需要指定一个字段作为外键&#xff0c;而这个外键又不符合以上四种约定时&#xff0c;就需要在IEntityTypeConfiguration实现类&#xff08;对应的配置类&#xff09;中使用Fluent API直接配置外键。理论上可以通过API直接指定一个属性&#xff0c;…

HTTP快速入门

HTTP报文结构 HTTP 协议主要由三大部分组成&#xff1a; ● 起始行&#xff08;start line&#xff09;&#xff1a;描述请求或响应的基本信息&#xff1b; ● 头部字段&#xff08;header&#xff09;&#xff1a;使用 key-value 形式更详细地说明报文&#xff1b; ● 消息正…

vue 页面导出gif图片 img 导出gif 超简单~

1.首先需要新建一个文件件 新建gif文件夹。这两个文件在文章最后面需要可自提 2.出gif分为两种情况 第一种情况 页面是img标签&#xff0c;直接导出图片作为gif 第二种情况 页面是div标签&#xff0c;需要导出div里面的图片作为gif 2.1页面是img标签&#xff0c;直接导出图…

[论文阅读]Distilling ChatGPT for Explainable Automated Student Answer Assessment

Distilling ChatGPT for Explainable Automated Student Answer Assessment http://arxiv.org/abs/2305.12962 简要概述 文章的背景是 教育领域的学生答题评估&#xff0c;传统的评估需要高成本的人工&#xff0c;随着CHATGPT的发展&#xff0c;研究人员发现这种能够有效处理…

嵌入式QT中基本工程模板分析

大家好,今天主要来分享一下,如何分析一下QT的工程代码文件。 第一:QT工程分析

CentOS安装NVIDIA驱动、CUDA以及nvidia-container-toolkit

0.提前准备 0.1.更新yum源&#xff08;以阿里为例&#xff09; 0.1.1 备份当前的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 0.1.2 下载新的CentOS-Base.repo 到/etc/yum.repos.d/ CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base…

Xilinx UltraScale系列FPGA纯verilog图像缩放,工程项目解决方案,提供2套工程源码和技术支持

目录 1、前言工程概述免责声明FPGA高端图像处理培训 2、相关方案推荐我这里已有的FPGA图像缩放方案本方案在Xilinx Artix7 系列FPGA上的应用本方案在Xilinx Kintex7 系列FPGA上的应用本方案在Xilinx Zynq7000 系列FPGA上的应用本方案在国产FPGA紫光同创系列上的应用本方案在国产…

Java爬虫API:获取商品详情数据的利器

为什么选择Java爬虫API 强大的库支持&#xff1a;Java拥有丰富的网络编程库&#xff0c;如Apache HttpClient、OkHttp等&#xff0c;这些库提供了强大的HTTP请求功能&#xff0c;使得发送请求和处理响应变得简单。高效的数据处理&#xff1a;Java的数据处理能力&#xff0c;结…

C语言:单链表(不带头节点)

目录 一、单链表概念 单链表的特点 二、单链表的实现 1、打印函数的实现 2、尾插函数的实现 3、全部函数的实现 总结&#xff1a; 一、单链表概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。…

沈阳乐晟睿浩科技有限公司:引领抖音小店迈向新纪元

在当今数字化浪潮汹涌的时代&#xff0c;电子商务以其独特的魅力和无限潜力&#xff0c;正深刻改变着人们的消费习惯与商业模式。在这场变革中&#xff0c;沈阳乐晟睿浩科技有限公司凭借其敏锐的市场洞察力和卓越的技术实力&#xff0c;成为了抖音小店领域的佼佼者&#xff0c;…