springboot使用hibernate validator
前言
在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦:
- 验证代码繁琐,重复劳动
- 方法内代码显得冗长
- 每次要看哪些参数验证是否完整,需要去翻阅验证逻辑代码
hibernate validator(官方文档)提供了一套比较完善、便捷的验证实现方式。
spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依赖。
一、常见的注解
Bean Validation 中内置的 constraint
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
二、hibernate validator校验demo
先来看一个简单的demo
public class StudentDto {
@NotBlank(message="名称不能为空")
private String name;
@NotBlank(message="年级不能为空")
@Pattern(regexp="^[0-9]{1,2}$",message="年级不正确")
private String grade;
@Min(value=,message="年龄必须大于6")
@Max(value=,message="年龄必须小于12")
private int age;
@Past(message="出生日期必须是过去的日期")
private Date birthDate;
....set get方法省略
@ApiOperation(value="hibernate validate验证")
@PostMapping("/validate")
public Object validate(@RequestBody @Valid StudentDto studentDto,BindingResult result){
Map<String,Object> retMap = new HashMap<String,Object>();
if(result.hasErrors()){
for (ObjectError error : result.getAllErrors()) {
System.out.println(error.getDefaultMessage());
}
}
return retMap;
}
post接口请求,输入
{
"age": 1,
"birthDate": "2019-12-20",
"grade": "string",
"name": "string"
}
结果输入
年级不正确
年龄必须大于6
三、hibernate的校验模式
细心的读者肯定发现了:上面例子中一次性返回了所有验证不通过的集合,通常按顺序验证到第一个字段不符合验证要求时,就可以直接拒绝请求了。Hibernate Validator有以下两种验证模式:
1、普通模式(默认是这个模式)
普通模式(会校验完所有的属性,然后返回所有的验证失败信息)
2、快速失败返回模式
快速失败返回模式(只要有一个验证失败,则返回),(hibernate.validator.fail_fast:true 快速失败返回模式 false 普通模式)
@Configuration
public class ValidatorConfiguration {
@Bean
public Validator validator(){
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
//(hibernate.validator.fail_fast:true 快速失败返回模式 false 普通模式)
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator(); return validator;
}
}
四、hibernate的两种校验
1、@RequestBody校验
以上所述是@RequestBody校验
2、@RequestParam校验
一般在处理Get请求(或参数比较少)的时候,会使用@RequestParam校验方式:如
@ApiOperation(value="hibernate validate param验证")
@GetMapping("/validateParem")
public Object validateParam(
@RequestParam(name = "grade", required = true) int grade,
@RequestParam(name = "classroom", required = true) int classroom){
Map<String,Object> retMap = new HashMap<String,Object>();
System.out.println(grade + "," + classroom);
return retMap;
}
使用@Valid注解,对RequestParam对应的参数进行注解,是无效的,需要使用@Validated注解来使得验证生效。如下所示:
a.此时需要使用MethodValidationPostProcessor 的Bean:
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator());
return postProcessor;
}
b.方法所在的Controller上加注解@Validated
@RestController
@Validated
public class HelloController {
@ApiOperation(value="hibernate validate param验证")
@GetMapping("/validateParem")
public Object validateParam(
@Range(min = , max = , message = "年级只能从1-9")
@RequestParam(name = "grade", required = true) int grade,
@Min(value = , message = "班级最小只能1")
@Max(value = , message = "班级最大只能99")
@RequestParam(name = "classroom", required = true) int classroom){
Map<String,Object> retMap = new HashMap<String,Object>();
System.out.println(grade + "," + classroom);
return retMap;
}
}
c.返回验证信息提示
可以看到:验证不通过时,抛出了ConstraintViolationException异常,使用同一捕获异常处理:
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
@ExceptionHandler
@ResponseBody
@ResponseStatus
public String handle(ValidationException exception) {
if(exception instanceof ConstraintViolationException){
ConstraintViolationException exs = (ConstraintViolationException) exception;
Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
for (ConstraintViolation<?> item : violations) {
//打印验证不通过的信息
System.out.println(item.getMessage());
}
}
return "bad request, " ;
}
}
d.验证
浏览器发起请求 http://localhost:8080/validateParem?grade=11111&classroom=22222
配置快速失败返回的MethodValidationPostProcessor 时输出信息如下:
年级只能从1-9
3、model校验
a.需要引入的包
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
b.待校验的model
@Data
public class Demo2 {
@Length(min = , max = , message = "length长度在[5,17]之间")
private String length; /**@Size不能验证Integer,适用于String, Collection, Map and arrays*/
@Size(min = , max = , message = "size在[1,3]之间")
private String age; @Range(min = , max = , message = "range在[150,250]之间")
private int high; @Size(min = ,max = ,message = "list的Size在[3,5]")
private List<String> list;
c.验证model
@Autowired
private Validator validator; @RequestMapping("/validateModel")
public void demo3(){
Demo2 demo2 = new Demo2();
demo2.setAge("111");
demo2.setHigh();
demo2.setLength("ABCDE");
demo2.setList(new ArrayList<String>(){{add("111");add("222");add("333");}});
Set<ConstraintViolation<Demo2>> violationSet = validator.validate(demo2);
for (ConstraintViolation<Demo2> model : violationSet) {
System.out.println(model.getMessage());
}
}
b.验证
后台会打印如下信息:
range在[150,250]之间
4、对象级联校验
对象内部包含另一个对象作为属性,属性上加@Valid,可以验证作为属性的对象内部的验证:(验证Demo2示例时,可以验证Demo2的字段)
a.待验证的model Demo2,Demo3
@Data
public class Demo2 {
@Size(min = ,max = ,message = "list的Size在[3,5]")
private List<String> list; @NotNull
@Valid
private Demo3 demo3; @Data
public class Demo3 {
@Length(min = , max = , message = "length长度在[5,17]之间")
private String extField;
b.级联校验
@Autowired
private Validator validator; @GetMapping("/validateModelCascade")
public void demo3(){
Demo2 demo2 = new Demo2();
demo2.setList(new ArrayList<String>(){{add("111");add("222");add("333");}});
Demo3 demo3 = new Demo3();
demo3.setExtField("22");
demo2.setDemo3(demo3);
Set<ConstraintViolation<Demo2>> violationSet = validator.validate(demo2);
for (ConstraintViolation<Demo2> model : violationSet) {
System.out.println(model.getMessage());
}
}
c.验证,后台打印如下:
length长度在[5,17]之间
5、分组校验
暂无
五、自定义验证器
暂无
六、参考资料
参考资料:
转自:https://www.cnblogs.com/mr-yang-localhost/p/7812038.html
引用:http://docs.jboss.org/hibernate/validator/4.2/reference/zh-CN/html_single/#validator-gettingstarted
springboot使用hibernate validator的更多相关文章
- springboot使用hibernate validator校验,Bean Validation校验
第一个地址:springboot使用hibernate validator校验,Bean Validation校验
- springboot使用hibernate validator校验
一.参数校验 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗长 每次要 ...
- springboot使用hibernate validator校验方式
一.参数校验 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗长 每次要 ...
- SpringBoot整合Hibernate Validator实现参数验证功能
在前后端分离的开发模式中,后端对前端传入的参数的校验成了必不可少的一个环节.但是在多参数的情况下,在controller层加上参数验证,会显得特别臃肿,并且会有许多的重复代码.这里可以引用Hibern ...
- Java笔记 #07# Hibernate Validator
Hibernate Validator是Spring Boot默认附带的标准校验API(javax.validation)实现. 应用实例(配合切面) 采用注解定义切面.java @Aspect @C ...
- SpringBoot 2 快速整合 | Hibernate Validator 数据校验
概述 在开发RESTFull API 和普通的表单提交都需要对用户提交的数据进行校验,例如:用户姓名不能为空,年龄必须大于0 等等.这里我们主要说的是后台的校验,在 SpringBoot 中我们可以通 ...
- spring 项目中使用 hibernate validator验证输入参数
1 hibernate validator 官方文档:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_si ...
- 用spring的@Validated注解和org.hibernate.validator.constraints.*的一些注解在后台完成数据校验
这个demo主要是让spring的@Validated注解和hibernate支持JSR数据校验的一些注解结合起来,完成数据校验.这个demo用的是springboot. 首先domain对象Foo的 ...
- java.lang.NoClassDefFoundError: org/hibernate/validator/internal/engine/DefaultClockProvider
①在springboot的spring-boot-starter-web默认引入了以下依赖: <dependency> <groupId>com.fasterxml.jacks ...
随机推荐
- 社交媒体登录Spring Social的源码解析
在上一篇文章中我们给大家介绍了OAuth2授权标准,并且着重介绍了OAuth2的授权码认证模式.目前绝大多数的社交媒体平台,都是通过OAuth2授权码认证模式对外开放接口(登录认证及用户信息接口等). ...
- 华为云EI人脸识别接口初探
0. 准备工作 开户及申请开通人脸识别服务,可以参考https://education.huaweicloud.com:8443/courses/course-v1:HuaweiX+CBUCNXE01 ...
- luogu P1938 [USACO09NOV]找工就业Job Hunt
题目描述 奶牛们正在找工作.农场主约翰知道后,鼓励奶牛们四处碰碰运气.而且他还加了一条要求:一头牛在一个城市最多只能赚D(1≤D≤1000)美元,然后它必须到另一座城市工作.当然,它可以在别处工作一阵 ...
- 学习ThinkPHP的第23天---门面、钩子与行为
一.门面(facade) 门面在ThinkPHP中可以理解为一个代理商,有了它可以灵活的去使用其中的类. 二.钩子和行为 钩子也可以说是插件,就是程序运行到某个位置,我们用钩子把这个程序截住,去执行所 ...
- 基于webpack实现多html页面开发框架八 html引入图片打包和公共页面模块复用
一.解决什么问题 1.html中img引入的图片地址没有被替换,找不到图片 2.html公共部分复用问题,如头部.底部.浮动层等 二.html中img引入图片问题解决 1.在index.html插入i ...
- 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享
写在前面的话&&About me 网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的:网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的. 我不是要 ...
- nginx的一些知识(一)
第8章 web网站的搭建 curl -Lv 网站地址:查看网站的请求信息和响应信息,并且会将结果输出出来 8.1 web网站的的传输原理过程 会进行DNS的解析 进行客户端和服务端进行三次握手协议 客 ...
- FPGA之驱动sdram控制兼容性移植实验
cb早在2012年就推出了VIP 视频开发板 V1.4 这套开发板是ep2的,摄像头是ov7670,虽然不如当前的vip20强大,但也算是其雏形. 在vip20后期,cb对sdram以及其他模块进行 ...
- synchronized,ReentrantLock解决锁冲突,脏读的问题
最常见的秒杀系统,解决思路就是从前端.后台服务.数据库层层去掉负载,以达到平衡 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLo ...
- 二、Vue 页面渲染过程
前言 上篇博文我们依葫芦画瓢已经将hello world 展现在界面上啦,但是是不是感觉新虚虚的,总觉得这么多文件,项目怎么就启动起来了呢?怎么访问到8080 端口就能进入到我们的首页呢.整个的流程是 ...