bean validation校验方法参数_Spring Boot 之使用 validation 验证参数

前言

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger种一棵树最好的时间是十年前,其次是现在
我知道很多人不玩qq了,但是怀旧一下,欢迎加入六脉神剑Java菜鸟学习群,群聊号码:549684836 鼓励大家在技术的路上写博客

絮叨

这个东西应该是我们撸业务最常用的组件之一了,因为之前小六六也是自己就是照着用,也没说全面的去了解一下这块,今天小六六就带大家一起来梳理梳理哈。

JSR-303 简介

JSR-303 是 JavaEE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是 Hibernate Validator。此实现与 Hibernate ORM 没有任何关系。JSR-303 用于对 Java Bean 中的字段的值进行验证。Spring MVC 3.x 之中也大力支持 JSR-303,可以在控制器中使用注解的方式对表单提交的数据方便地验证。Spring 4.0 开始支持 Bean Validation 功能。JSR-303 基本的校验规则

空检查

  • @Null 验证对象是否为 null
  • @NotNull 验证对象是否不为 null, 无法查检长度为 0 的字符串
  • @NotBlank 检查约束字符串是不是 Null 还有被 Trim 的长度是否大于 0,只对字符串,且会去掉前后空格
  • @NotEmpty 检查约束元素是否为 NULL 或者是 EMPTY

布尔检查

  • @AssertTrue 验证 Boolean 对象是否为 true
  • @AssertFalse 验证 Boolean 对象是否为 false

长度检查

@Size(min=, max=) 验证对象(Array, Collection , Map, String)长度是否在给定的范围之内 @Length(min=, max=) 验证字符串长度介于 min 和 max 之间

日期检查

  • @Past 验证 Date 和 Calendar 对象是否在当前时间之前,验证成立的话被注释的元素一定是一个过去的日期
  • @Future 验证 Date 和 Calendar 对象是否在当前时间之后 ,验证成立的话被注释的元素一定是一个将来的日期

正则检查

@Pattern 验证 String 对象是否符合正则表达式的规则,被注释的元素符合制定的正则表达式 - regexp:正则表达式 - flags:指定 Pattern.Flag 的数组,表示正则表达式的相关选项

数值检查

注意:建议使用在 String ,Integer 类型,不建议使用在 int 类型上,因为表单值为 “” 时无法转换为 int,但可以转换为 String 为 “”,Integer 为 null

  • @Min 验证 Number 和 String 对象是否大等于指定的值
  • @Max 验证 Number 和 String 对象是否小等于指定的值
  • @DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过 BigDecimal定义的最大值的字符串表示 .小数 存在精度
  • @DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过 BigDecimal定义的最小值的字符串表示 .小数 存在精度
  • @Digits 验证 Number 和 String 的构成是否合法
  • @Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,integer 指定整数精度,fraction 指定小数精度
  • @Range(min=, max=) 被指定的元素必须在合适的范围内
  • @Range(min=10000,max=50000,message=”range.bean.wage”)
  • @Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个 map,则对其中的值部分进行校验.(是否进行递归验证)
  • @CreditCardNumber 信用卡验证
  • @Email 验证是否是邮件地址,如果为 null,不进行验证,算通过验证
  • @ScriptAssert(lang= ,script=, alias=)
  • @URL(protocol=,host=, port=,regexp=, flags=)

使用

至于使用的话,小六六这边就不一一的举例了,相信大家应该都会,可能平时没有那么详细的了解过,所以这次我就是好好给大家复习一下哈哈

@Data
public class User {
 
 /** id */
 @NotNull(message="id不能为空")
 private Long id;
 
 /** 姓名 */
 @NotBlank(message="姓名不能为空")
 private String name;
 
 /** 年龄 */
 @NotNull(message="年龄不能为空")
 @Max(message="年龄不能超过120岁", value = 120)
 @Min(message="年龄不能小于1岁", value = 1)
 private Integer age;
 
 /** 创建时间 */
 @Future
 private Date createTime;
}
 

然后在controller层里,使用@Valid就好了

 /**
  * 校验不通过时直接抛异常
  * @param user
  * @return
  */
 @PostMapping("/test1")
 public Object test1(@RequestBody @Valid User user) {
  return "操作成功!";
 }

Spring Validation的3种执行校验方式

第一种:在Controller方法参数前加@Valid注解——校验不通过时直接抛异常

调用时会抛出一个org.springframework.web.bind.MethodArgumentNotValidException异常:

2019-04-21 11:35:28.600  WARN 10852 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.Object com.example.validation.UserController.test1(com.example.validation.User) with 3 errors: [Field error in object 'user' on field 'createTime': rejected value [Mon Dec 31 08:00:00 CST 2018]; codes [Future.user.createTime,Future.createTime,Future.java.util.Date,Future]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.createTime,createTime]; arguments []; default message [createTime]]; default message [需要是一个将来的时间]] [Field error in object 'user' on field 'age': rejected value [0]; codes [Min.user.age,Min.age,Min.java.lang.Integer,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.age,age]; arguments []; default message [age],1]; default message [年龄不能小于1岁]] [Field error in object 'user' on field 'name': rejected value []; codes [NotBlank.user.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.name,name]; arguments []; default message [name]]; default message [姓名不能为空]] ]

其实像这种,我想大家肯定是要配合全局统一异常来处理,其实还是很好,目前我就是这么干的。推荐指数 3星

第二种:在Controller方法参数前加@Valid注解,参数后面定义一个BindingResult类型参数——执行时会将校验结果放进bindingResult里面,用户自行判断并处理

   /**
  * 将校验结果放进BindingResult里面,用户自行判断并处理
  * @param user
  * @param bindingResult
  * @return
  */
 @PostMapping("/test2")
 public Object test2(@RequestBody @Valid User user, BindingResult bindingResult) {
  // 参数校验
  if (bindingResult.hasErrors()) {
   String messages = bindingResult.getAllErrors()
    .stream()
    .map(ObjectError::getDefaultMessage)
    .reduce((m1, m2) -> m1 + ";" + m2)
    .orElse("参数输入有误!");
   throw new IllegalArgumentException(messages);
  }
  
  return "操作成功!";

把结果封装到一个BindingResult中,然后再通过自己去封装要抛出的信息,这种做法也可以,就是每个controller都要写,不那么适用,推荐指数 2星

第三种:用户手动调用对应API执行校验——Validation.buildDefault ValidatorFactory().getValidator().validate(xxx)

   /**
  * 用户手动调用对应API执行校验
  * @param user
  * @return
  */
 @PostMapping("/test3")
 public Object test3(@RequestBody User user) {
  // 参数校验
  validate(user);
  
  return "操作成功!";
 }
 
 private void validate(@Valid User user) {
  Set> validateSet = Validation.buildDefaultValidatorFactory()
    .getValidator()
    .validate(user, new Class[0]);if (!CollectionUtils.isEmpty(validateSet)) {
    String messages = validateSet.stream()
     .map(ConstraintViolation::getMessage)
     .reduce((m1, m2) -> m1 + ";" + m2)
     .orElse("参数输入有误!");
    throw new IllegalArgumentException(messages);
   }
}

这种其实原理也差不多,但是看起来也是一样,没有那么优雅,推荐指数 2星

结尾

其实这三种用法的原理都是一样的,只是使用的形式不一样了,其实看你自己把,哈哈。

参考

  • JSR
91e595d150eb5024038de3448da3e9d5.png

日常求赞

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是真粉

创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见

六脉神剑 | 文 【原创】如果本篇博客有任何错误,请批评指教,不胜感激 !

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

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

相关文章

LeetCode 891. 子序列宽度之和(数学)

文章目录1. 题目2. 解题1. 题目 给定一个整数数组 A ,考虑 A 的所有非空子序列。 对于任意序列 S ,设 S 的宽度是 S 的最大元素和最小元素的差。 返回 A 的所有子序列的宽度之和。 由于答案可能非常大,请返回答案模 10^97。 示例&#x…

hive建表语句_Hive数据如何同步到MaxCompute之实践讲解

摘要:本次分享主要介绍 Hive数据如何迁移到MaxCompute。MMA(MaxCompute Migration Assist)是一款MaxCompute数据迁移工具,本文将为大家介绍MMA工具的功能、技术架构和实现原理,再通过实际操作MMA,演示将Hive数据迁移到MaxCompute。…

Java 包及访问权限

文章目录1. package 包2. import3. JDK常见的包4. 访问权限5. jar 压缩1. package 包 作用:防止不同的人写的类的名称相同冲突了, package testPackage1.java; class testPg {public String talk(){return "talk()";} } class testAnother{p…

java phaser用法_第3章Phaser的使用-(java并发编程核心方法与框架)

3.1 Phaser的使用3.2 类Phaser的arriveAndAwaitAdvance()方法测试13.3 类Phaser的arriveAndAwaitAdvance()方法测试23.4 类Phaser的arriveAndDeregister()方法测试3.5 类Phaser的getPhase()和onAdvance()方法测试3.6 类Phaser的getRegisteredParties()方法和register()测试3.7 …

html选项卡_适用于Mac的最佳HTML文本编辑器,编码开发必备

一个好的文本编辑器对于想要建立网站或进行编码的任何人都是必不可少的。这对于习惯于面面俱到的环境的Mac开发人员而言更加明显。对于他们来说存在一系列不同的优质软件之选。今天小编将介绍几款Mac上好用的HTML文本编辑器,对于每一款文本编辑器,小编将…

java 判断请求为 ajax请求_Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求...

Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求java 判断请求是不是ajax请求,Java判断是否为ajax请求>>>>>>>>>>>>>>>>>>>>>>>>>>>>&…

java set hashcode_Java学习笔记_180724_HashSet_hashCode()

HashSet泛型E必须重写hashCode方法,否则会导致add结果与预期不符如class NewClass{String s;public NewClass(String s){this.ss;}overridepublic int hashCode(){//此处返回字符串s的hashCode()return s.hashCode();}}NewClass n new NewClass("1");New…

LeetCode 1773. 统计匹配检索规则的物品数量

文章目录1. 题目2. 解题1. 题目 给你一个数组 items ,其中 items[i] [typei, colori, namei] ,描述第 i 件物品的类型、颜色以及名称。 另给你一条由两个字符串 ruleKey 和 ruleValue 表示的检索规则。 如果第 i 件物品能满足下述条件之一&#xff0…

LeetCode 1774. 最接近目标价格的甜点成本(DFS / 01背包)

文章目录1. 题目2. 解题1. 题目 你打算做甜点,现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则: 必须选择 一种 冰激凌基料。可以添加 一种或多种 配料,也可以不添加任何配料。每种类型的配…

线程间通信的几种方法_并发编程中的线程间通信

线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其他线程的信号。线程通信常用的方式有:wait/notify 等待Volatile 内存共享CountDownLatch 并发工具使用 ReentrantLock 结合 Condition基本LockSupport实现线程间的阻塞和唤醒方式一&am…

【IOS】Target membership

Target membership是指XCode中,一个文件属于哪一个工程,在XCode左侧的工程面板中选中一个文件,在XCode右侧的属性面板中会显示其Target Membership,如下图。 当前的文件AppDelegate.m属于书谱这个Target。 Target Membership的一些…

LeetCode 1775. 通过最少操作次数使数组的和相等(贪心+双指针)

文章目录1. 题目2. 解题1. 题目 给你两个长度可能不等的整数数组 nums1 和 nums2 。 两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。 每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值&am…

LeetCode 1776. 车队 II(单调栈)

文章目录1. 题目2. 解题1. 题目 在一条单车道上有 n 辆车,它们朝着同样的方向行驶。 给你一个长度为 n 的数组 cars ,其中 cars[i] [positioni, speedi] ,它表示: positioni 是第 i 辆车和道路起点之间的距离(单位&…

wpf计算字符大小占像素_LCD作为终端显示字符串的过程

LCD作为终端显示字符串的过程1.本文目的2.资源评估3.显示原理4.嵌入式上汉字处理5.结果验证与展示6.总结1.本文目的做嵌入式图形开发,我们往往都会利用到各种GUI进行交互设计,但是对于GUI的字符串处理与中文字库显示,也许并不会特别关注&…

商城简单类图

转载于:https://www.cnblogs.com/stit/p/4125095.html

交换机的基本配置实验报告_无线网络设计配置即实验报告

工程师ACK接到一个小型图书馆的网络组建项目,根据目前流行的网络组建以及项目地点的使用需要便捷性,采用AC控制的瘦AP模式。不需要AC来管理网络的AP是胖AP需要单独配置,有多少个AP就要配置多少次。组建模式:一楼划分20个VLAN,二楼…

Java 集合框架(List、Set、Map、Iterator、Stack、Properties)

文章目录1. ArrayList2. LinkedList3. HashSet4. TreeSet5. Iterator、ListIterator6. HashMap7. TreeMap8. Stack9. Properties 类读写简单 数据库相关文献:https://www.runoob.com/java/java-collections.html 1. ArrayList 类似动态数组 ArrayList al new Arr…

js获取当前url_javascript如何获取当前URL的主机名?

在javascript中可以使用location对象的hostname属性或者host属性来获取当前URL的主机名,下面本篇文章就来带大家认识这两种属性,希望对大家有所帮助。使用location hostname属性location hostname属性是用于返回当前URL的主机名;它会返回一个…

java访问数据库方式_java数据库访问(二)—JDBC方式(配合连接池)

上文记录了最基础的JDBC连接数据库的方法,但能看出一个问题,就是要不断的重复去创建connection和关闭connection,如果在对数据库的访问比较频繁的情况下,这种处理方式方式在性能方面是不合适的,下面使用JDBC配合数据库…

超频真的不难!G3258超频4.5GHz全攻略

奔腾G3258搭配主板详解【pconline 应用】目前DIY市场上最火热的装机组合莫过于奔腾20周年纪念版处理器G3258搭配B85芯片组主板,只要通过适当的超频,相对较低投入也能来不错的性能体验,因此在奔腾G3258还没上市时,业界对其充满期待…