一、JSR303校验

1.使用校验注解

<!--Valid--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>2.3.2.RELEASE</version></dependency><!--自定义注解--><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency>

(1)@NotNull
The annotated element must not be null. Accepts any type.
注解元素禁止为null,能够接收任何类型
(2)@NotEmpty
the annotated element must not be null nor empty.
该注解修饰的字段不能为null或""
Supported types are:
支持以下几种类型
CharSequence (length of character sequence is evaluated)
字符序列(字符序列长度的计算)
Collection (collection size is evaluated)
集合长度的计算
Map (map size is evaluated)
map长度的计算
Array (array length is evaluated)
数组长度的计算

(3)@NotBlank

The annotated element must not be null and must contain at least one non-whitespace character. Accepts CharSequence.
该注解不能为null,并且至少包含一个非空白字符。接收字符序列。

package com.atguigu.gulimall.product.entity;import com.atguigu.common.valid.AddGroup;
import com.atguigu.common.valid.ListValue;
import com.atguigu.common.valid.UpdateGroup;
import com.atguigu.common.valid.UpdateStatusGroup;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.hibernate.validator.constraints.URL;import javax.validation.constraints.*;
import java.io.Serializable;/*** 品牌* * @author steven* @email steven@gmail.com* @date 2022-01-08 16:31:09*/
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 品牌id*/@Null(message = "新增品牌ID必须为空",groups = {AddGroup.class})@NotNull(message = "修改是品牌ID不能为空",groups = {UpdateGroup.class})@TableIdprivate Long brandId;/*** 品牌名*/@NotBlank(message = "品牌名不能为空",groups = {AddGroup.class,UpdateGroup.class})private String name;/*** 品牌logo地址*/@NotEmpty(message = "商品logo地址不能为空",groups = {AddGroup.class})//,groups = {AddGroup.class, UpdateGroup.class}@URL(message = "logo必须是一个合法的url地址",groups = {AddGroup.class,UpdateGroup.class})private String logo;/*** 介绍*/private String descript;/*** 显示状态[0-不显示;1-显示]*/@NotNull(message = "状态不能为空",groups = {AddGroup.class,UpdateStatusGroup.class})@ListValue(vals = {0,1},groups = {AddGroup.class, UpdateStatusGroup.class})private Integer showStatus;/*** 检索首字母*/@NotBlank(message = "检索首字母不能为空",groups = {AddGroup.class})@Pattern(regexp = "^[a-zA-Z]$",message = "检索首字母必须是一个字母",groups = {AddGroup.class,UpdateGroup.class})private String firstLetter;/*** 排序*/@NotNull(message = "排序字段不能为空",groups = {AddGroup.class})@Min(value = 0,message = "排序必须大于等于0",groups = {AddGroup.class,UpdateGroup.class})private Integer sort;
}

2:在请求方法种,使用校验注解@Validated,开启校验

/*** 修改*/@RequestMapping("/update")public R update(@Validated @RequestBody BrandEntity brand){brandService.updateById(brand);return R.ok();}

这些错误消息定义在“hibernate-validator”的“\org\hibernate\validator\ValidationMessages_zh_CN.properties”文件中。在该文件中定义了很多的错误规则:

javax.validation.constraints.AssertFalse.message     = 只能为false
javax.validation.constraints.AssertTrue.message      = 只能为true
javax.validation.constraints.DecimalMax.message      = 必须小于或等于{value}
javax.validation.constraints.DecimalMin.message      = 必须大于或等于{value}
javax.validation.constraints.Digits.message          = 数字的值超出了允许范围(只允许在{integer}位整数和{fraction}位小数范围内)
javax.validation.constraints.Email.message           = 不是一个合法的电子邮件地址
javax.validation.constraints.Future.message          = 需要是一个将来的时间
javax.validation.constraints.FutureOrPresent.message = 需要是一个将来或现在的时间
javax.validation.constraints.Max.message             = 最大不能超过{value}
javax.validation.constraints.Min.message             = 最小不能小于{value}
javax.validation.constraints.Negative.message        = 必须是负数
javax.validation.constraints.NegativeOrZero.message  = 必须是负数或零
javax.validation.constraints.NotBlank.message        = 不能为空
javax.validation.constraints.NotEmpty.message        = 不能为空
javax.validation.constraints.NotNull.message         = 不能为null
javax.validation.constraints.Null.message            = 必须为null
javax.validation.constraints.Past.message            = 需要是一个过去的时间
javax.validation.constraints.PastOrPresent.message   = 需要是一个过去或现在的时间
javax.validation.constraints.Pattern.message         = 需要匹配正则表达式"{regexp}"
javax.validation.constraints.Positive.message        = 必须是正数
javax.validation.constraints.PositiveOrZero.message  = 必须是正数或零
javax.validation.constraints.Size.message            = 个数必须在{min}和{max}之间org.hibernate.validator.constraints.CreditCardNumber.message        = 不合法的信用卡号码
org.hibernate.validator.constraints.Currency.message                = 不合法的货币 (必须是{value}其中之一)
org.hibernate.validator.constraints.EAN.message                     = 不合法的{type}条形码
org.hibernate.validator.constraints.Email.message                   = 不是一个合法的电子邮件地址
org.hibernate.validator.constraints.Length.message                  = 长度需要在{min}和{max}之间
org.hibernate.validator.constraints.CodePointLength.message         = 长度需要在{min}和{max}之间
org.hibernate.validator.constraints.LuhnCheck.message               = ${validatedValue}的校验码不合法, Luhn模10校验和不匹配
org.hibernate.validator.constraints.Mod10Check.message              = ${validatedValue}的校验码不合法, 模10校验和不匹配
org.hibernate.validator.constraints.Mod11Check.message              = ${validatedValue}的校验码不合法, 模11校验和不匹配
org.hibernate.validator.constraints.ModCheck.message                = ${validatedValue}的校验码不合法, ${modType}校验和不匹配
org.hibernate.validator.constraints.NotBlank.message                = 不能为空
org.hibernate.validator.constraints.NotEmpty.message                = 不能为空
org.hibernate.validator.constraints.ParametersScriptAssert.message  = 执行脚本表达式"{script}"没有返回期望结果
org.hibernate.validator.constraints.Range.message                   = 需要在{min}和{max}之间
org.hibernate.validator.constraints.SafeHtml.message                = 可能有不安全的HTML内容
org.hibernate.validator.constraints.ScriptAssert.message            = 执行脚本表达式"{script}"没有返回期望结果
org.hibernate.validator.constraints.URL.message                     = 需要是一个合法的URLorg.hibernate.validator.constraints.time.DurationMax.message        = 必须小于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小时'}${minutes == 0 ? '' : minutes += '分钟'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '纳秒'}
org.hibernate.validator.constraints.time.DurationMin.message        = 必须大于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小时'}${minutes == 0 ? '' : minutes += '分钟'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '纳秒'}

3:给校验的Bean后,紧跟一个BindResult,就可以获取到校验的结果。拿到校验的结果,就可以自定义的封装。

 public R save(@Validated @RequestBody BrandEntity brand, BindingResult bindingResult){Map<String,String> map = new HashMap<>();if(bindingResult.hasErrors()){bindingResult.getFieldErrors().stream().forEach(item->{String field = item.getField();String defaultMessage = item.getDefaultMessage();map.put(field, defaultMessage);});return R.error(400,"参数错误").put("data", map);}else{brandService.save(brand);return R.ok();}}

4.统一异常处理

可以使用SpringMvc所提供的@ControllerAdvice,通过“basePackages”能够说明处理哪些路径下的异常。

package com.bigdata.gulimall.product.exception;import com.bigdata.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;/*** 集中处理所有异常*/
@Slf4j
@RestControllerAdvice(basePackages = "com.bigdata.gulimall.product.controller")
public class GulimallExceptionAdvice {@ExceptionHandler(value = Exception.class)public R handleValidException(MethodArgumentNotValidException exception){Map<String,String> map=new HashMap<>();BindingResult bindingResult = exception.getBindingResult();bindingResult.getFieldErrors().forEach(fieldError -> {String message = fieldError.getDefaultMessage();String field = fieldError.getField();map.put(field,message);});log.error("数据校验出现问题{},异常类型{}",exception.getMessage(),exception.getClass());return R.error(400,"数据校验出现问题").put("data",map);}
}

二、 分组校验功能(完成多场景的复杂校验)

1、给校验注解,标注上groups,指定什么情况下才需要进行校验

如:指定在更新和添加的时候,都需要进行校验

@NotEmpty@NotBlank(message = "品牌名必须非空",groups = {UpdateGroup.class,AddGroup.class})private String name;

在这种情况下,没有指定分组的校验注解,默认是不起作用的。想要起作用就必须要加groups。

2、业务方法参数上使用@Validated注解

@Validated的value方法:
Specify one or more validation groups to apply to the validation step kicked off by this annotation.
指定一个或多个验证组以应用于此注释启动的验证步骤。
JSR-303 defines validation groups as custom annotations which an application declares for the sole purpose of using
them as type-safe group arguments, as implemented in SpringValidatorAdapter.
JSR-303 将验证组定义为自定义注释,应用程序声明的唯一目的是将它们用作类型安全组参数,如 SpringValidatorAdapter 中实现的那样。
Other SmartValidator implementations may support class arguments in other ways as well.
其他SmartValidator 实现也可以以其他方式支持类参数。

默认情况下,在分组校验情况下,没有指定指定分组的校验注解,将不会生效,它只会在不分组的情况下生效。

三、自定义校验功能

1.编写一个自定义的校验注解

@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {String message() default "{com.bigdata.common.valid.ListValue.message}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };int[] value() default {};
}

2.编写一个自定义的校验器

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {private Set<Integer> set=new HashSet<>();@Overridepublic void initialize(ListValue constraintAnnotation) {int[] value = constraintAnnotation.value();for (int i : value) {set.add(i);}}@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {return  set.contains(value);}
}

指向自定义校验类 @Constraint(validatedBy = { ListValueConstraintValidator.class})

编写自定义提示文件放到resource目录下 ValidationMessages.properties

com.atguigu.common.valid.ListValue.message=必须提交指定的值

SpringBoot接口参数校验相关推荐

  1. SpringBoot实现通用的接口参数校验

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:cipher juejin.im/post/5af3c25b ...

  2. java 接口参数验证_SpringBoot实现通用的接口参数校验

    作者:cipher 来源:http://39sd.cn/560BA 本文介绍基于Spring Boot和JDK8编写一个AOP,结合自定义注解实现通用的接口参数校验. 缘由 目前参数校验常用的方法是在 ...

  3. aop+注解 实现对实体类的字段校验_SpringBoot实现通用的接口参数校验

    来自:掘金,作者:cipher 链接:https://juejin.im/post/5af3c25b5188253064651c76 原文链接:http://www.ciphermagic.cn/sp ...

  4. springboot中参数校验(validation)使用

    文章目录 介绍: validation引入 可用约束(constraint) 应用实战 实体类 接口参数型 约束生效 实体型 介绍: 在开发中,会经常需要进行参数的校验,比如接口层.业务层.持久层等, ...

  5. 校验json格式_不来学一下SpringBoot统一参数校验?

    微服务架构之春招总结:SpringCloud.Docker.Dubbo与SpringBoot 一个SpringBoot问题就干趴下了?我却凭着这份PDF文档吊打面试官. 金三银四第一天,啃透这些Spr ...

  6. SpringBoot:参数校验的使用(validator)

    文章目录 SpringBoot参数校验的使用(validator) 一.validator简介 二.注解介绍 内置注解 扩展注解 三.validator的使用(手动校验) 创建校验工具类 对一个对象进 ...

  7. Springboot @Validated参数校验

    简单使用 Java API规范(JSR303)定义了Bean校验的标准validation-api,但没有提供实现.hibernate validation是对这个规范的实现,并增加了校验注解如@Em ...

  8. java校验参数防止攻击_程序员写接口参数校验,总是太多if else?一招让你避免体力活...

    对于写Java的程序员来说,不管是写单纯的接口.还是页面后台一把梭,后端参数校验的功能都是整个代码不可或缺的一部分,它可以从系统入口过滤掉一些不合法的数据,以确保我们的系统稳定. 还记得我刚入行Jav ...

  9. e0312 不存在用户定义的_更加灵活的参数校验,Spring-boot自定义参数校验注解

    上文我们讨论了如何使用@Min.@Max等注解进行参数校验,主要是针对基本数据类型和级联对象进行参数校验的演示,但是在实际中我们往往需要更为复杂的校验规则,比如注册用户的密码和确认密码进行校验,这个时 ...

最新文章

  1. mysql 日期_「5」学习MySQL日期与时间类型发现:要养成注重细节的习惯
  2. Fault,Error与Failure的联系与区别
  3. jmeter 正则表达式
  4. 详解虚函数的实现过程之多重继承(3)
  5. oracle 排序的分析函数,oracle下数据的排序分组row_number() over()--分析函数,可用于去重...
  6. leetcode--872. 叶子相似的树
  7. python的selenium模块_Python中Selenium模块的使用
  8. redis原子性读写操作之LUA脚本和watch机制
  9. pythoninit作用_简介Python中的__init__的作用
  10. 电脑如何连接蓝牙音箱_蓝牙音箱如何办理SRRC认证
  11. 如何在ROS环境中解码.bag格式数据
  12. 2D空间中求线段与圆的交点
  13. 小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_42、SpringBoot常用定时任务配置实战...
  14. cramer定理_线性代数部分重要定理总结
  15. C语言根号下的书写方法
  16. CDN架构原理、流量模型、网络调优
  17. 历时一年 Apache Spark 3.3.0 正式发布,新特性详解
  18. 在vue项目中使用骨架屏
  19. 在phpstudy中安装并使用ThinkPHP 5
  20. 2022-09-15 mysql列存储引擎-语法树转换

热门文章

  1. ssh免密登录方法不生效?Authentication refused: bad ownership or modes for directory
  2. 数据库常忽略小问题汇总
  3. nodejs新建服务器
  4. YYModel 源码解读(二)之YYClassInfo.h (1)
  5. CakePHP下使用paginator需要对多个字段排序的做法
  6. thinkphp URL相关
  7. python语言格式化输出_Python字符串格式化输出
  8. python数据读取失败无法启动应用_tensorflow初学者教程-读取数据集失败
  9. android wifimanager权限,Android 6.0.1 - 权限问题= wifiManager.getScanResults()返回0
  10. 用计算机图形学画字母,r 语言快速出图——单因素方差带字母显著性标记