# hibernate-validator
**Repository Path**: jujungfoxmail/hibernate-validator
## Basic Information
- **Project Name**: hibernate-validator
- **Description**: 学习hibernate-validator
- **Primary Language**: Java
- **License**: GPL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 0
- **Created**: 2020-07-30
- **Last Updated**: 2022-11-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# hibernate-validator
### 一、概述
Bean Validation源于JSR-303 ,而JSR303是 Java EE 6 中的一项子规范。JSR349、JSR380是其升级版,添加了一些新的特性。Oracle公司传统艺能,一流公司定标准,它们只定义了一些校验注解(Constraint),如@Null@NotNull@Pattern],位于javax.validation.constraints包下,只提供规范不提供实现。
Hibernate Validator是对这个规范的实现(不要和数据库ORM框架Hibernate联系在一起),并增加了一些自定义校验注解,如`@Email`、`@Length`、`@Range`,位于org.hibernate.validator.constraints包下。
这里贴上常用的注解和解释
| 注解 | 释义 |
| :-------------------------- | ------------------------------------------------------------ |
| @Null | 被注释的元素必须为 null |
| @NotNull | 被注释的元素必须不为 null |
| @AssertTrue | 被注释的元素必须为 true |
| @AssertFalse | 被注释的元素必须为 false |
| @Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
| @Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
| @DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
| @DecimalMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
| @Size(max, min) | 被注释的元素的大小必须在指定的范围内,元素必须为集合,代表集合个数 |
| @Digits (integer, fraction) | 被注释的元素必须是一个数字,其值必须在可接受的范围内 |
| @Past | 被注释的元素必须是一个过去的日期 |
| @Future | 被注释的元素必须是一个将来的日期 |
| @Email | 被注释的元素必须是电子邮箱地址 |
| @Length(min=, max=) | 被注释的字符串的大小必须在指定的范围内,必须为数组或者字符串,若微数组则表示为数组长度,字符串则表示为字符串长度 |
| @NotEmpty | 被注释的字符串的必须非空,**可以为空格,空字符串,null** |
| @Range(min=, max=) | 被注释的元素必须在合适的范围内 |
| @NotBlank | 被注释的字符串的必须非空,**不可以为空格,可以为空字符串,null** |
| @Pattern(regexp = ) | 正则表达式校验 |
### 二、基础使用
在实际的web项目开发中,我们无需手动引入依赖。当依赖spring-boot-starter-web这个starter时,会自动传递相应的Bean Validation依赖。但有一点需要注意,在更新版本的SpringBoot中,默认移除了Bean Validtion相关依赖。具体的对应关系可以参照如下表格:
| spring boot 版本 | validation依赖 |
| ---------------- | ------------------------------------------ |
| < 2.3.x | spring-boot-starter-web传递校验依赖 |
| > 2.3.x | 需要手动引入spring-boot-starter-validation |
注:以下的示例代码是基于spring-boot 2.3.0.RELEASE版本
工程依赖文件如下
```xml
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
```
**Controller层校验**
假设我们实现了一个Spring REST控制器,想要验证由客户端传入的参数。根据请求方式、携带的内容以及实际应用场景,一般有三类:
- POST Request Body;
- GET PathVariable (如/foos/{id});
- GET Query Param(如url?q=param)
上面三种基本覆盖了大部分的开发场景
**1.验证Request Body**
接收参数的包装类
```java
@Getter
@Setter
public class RequestParam {
@Min(1)
@Max(5)
private Integer number;
@Email
private String email;
}
```
接收请求的controller
```java
@RestController
public class ValidateRequestBodyController {
@PostMapping("/validateBody")
public ResponseEntity validateBody(@Valid @RequestBody RequestParam param) {
return ResponseEntity.ok("valid");
}
}
```
注意:此时注解标注的位置,**必须放在方法参数上**,放在类上会导致校验不生效,行为不符合预期。此外,针对这种情形`@Valid`和@`Validated`两个注解可以混用。 使用`@Validated`时也需要放在参数列表中,放在类上和放在方法上都会导致没有校验。
如果校验失败,会抛出一个**MethodArgumentNotValidException**异常,Spring默认会把这个转为400(Bad Request)请求。

请求:
```json
{
"number":123456,
"email":"123456@qq.com"
}
```
返回:
```json
{
"timestamp": "2020-07-30T10:18:19.435+00:00",
"status": 400,
"error": "Bad Request",
"message": "",
"path": "/validateBody"
}
```
异常:
```text
org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0]...
```
在实际项目开发中,通常会用 ExceptionHandler处理该异常,包裹返回一个更友好的提示:
定义全局异常处理器:
```java
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理POST请求参数校验异常
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity