Spring Web项目中需要校验参数的正确性,JSR 303是其规范,
hibernate-validator
是该规范的一个实现,使用他可以实现统一的参数校验
- Java Bean Validation的初步使用
- Java Bean Validation自定义注解
- Java Bean Validation分组校验
- Java Bean Validation校验@PathVariable和@RequestParam
添加依赖
因为在Spring Boot中默认已经包含了Hibernate Validator
,所以不需要再引入额外的Jar包
配置规则
@Data
public class Person {
@Null(message = "id should be empty")
private Integer id;
@Length(min = 2, max = 10, message = "name的长度为[2-10]之间")
@NotBlank(message = "name should not be empty")
private String name;
@Min(18)
@Max(130)
private Integer age;
@NotNull(message = "gender should not be empty")
private Boolean gender;
@Null(message = "createTime should be empty")
private LocalDateTime createTime;
@Null(message = "updateTime should be empty")
private LocalDateTime updateTime;
}
@Min @Max @Length
等规则都是在字段不为Null的时候校验,如果字段为Null,则不使用这种规则。如果一定要满足,则还需要添加规则@NotNull
Controller中校验规则
- 添加注解
@Valid
@Slf4j
@SpringBootApplication
@RestController
public class ValidationApplication {
public static void main(String[] args) {
SpringApplication.run(ValidationApplication.class, args);
}
@GetMapping("ping")
public String ping() {
return "success";
}
//@Valid注解引导Spring完成参数校验
@PostMapping("create")
public WebResult create(@Valid @RequestBody Person person) {
return new WebResult<>(person.getName());
}
}
测试
- 请求的参数
{
"name": "tenmao"
}
- 返回的结果
{
"timestamp": "2019-05-03T10:07:04.611+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"NotNull.person.gender",
"NotNull.gender",
"NotNull.java.lang.Boolean",
"NotNull"
],
"arguments": [
{
"codes": [
"person.gender",
"gender"
],
"arguments": null,
"defaultMessage": "gender",
"code": "gender"
}
],
"defaultMessage": "gender should not be empty",
"objectName": "person",
"field": "gender",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotNull"
}
],
"message": "Validation failed for object='person'. Error count: 1",
"path": "/create"
}
校验的结果显示很丰富,但是一般情况下我们并不需要这么详细的校验结果。
自定义返回结果
因为在一般的Restful API接口中,不会把Spring Boot的原始错误信息返回,而是封装成统一的返回格式。
比如
{
"code":0,
"msg":"success",
"data":null
}
- 自定义返回值:在
ValidationApplication
的后面添加以下参数校验的异常处理
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public WebResult handleValidationExceptions(
MethodArgumentNotValidException ex) {
WebResult result = new WebResult<>();
result.setCode(400);
String errorMsg = ex.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining("\n", "[", "]"));
result.setMsg(errorMsg);
return result;
}
- 调整后的结果如下
{
"code": 400,
"msg": "[gender should not be empty]",
"data": null
}
手动校验
在一些非Spring Web项目中,特别是数据收集系统中,也需要对参数进行校验,使用hibernate-validator
也会更加便利。
- 手动校验示例如下:
Person person = new Person();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set> violationSet = validator.validate(person);
for (ConstraintViolation violation : violationSet) {
System.out.println(violation.getMessage());
}
规则注解列表
/**
* 认识一些校验注解Hibernate Validator
*
* @NotNull 值不能为空
* @Null 值必须为空
* @Pattern(regex= ) 字符串必须匹配正则表达式
* @Size(min= , max= )集合的元素数量必须在min和max之间
* @CreditCardNumber(ignoreNoDigitCharacters=) 字符串必须是信用卡的卡号 按照美国的标准
* @Email 字符串必须是Email地址
* @Length(mix= , max=) 校验字符串的长度
* @NotBlank 字符串必须有字符
* @NotEmpty 字符串不能为Null, 集合有元素
* @Range(min= , max=) 数字必须大于等于min ,小于等于max
* @SafeHtml 字符串是安全的html
* @URL 字符串是合法的URL
*
* @AssertFalse 值必须是false
* @AssertTrue 值必须是true
*
* // 此属性既可以是字符串 也可以是数字 inclusive 是包含的意思
* @DecimalMax(value= ,inclusive=) 值必须小于等于value 指定的值
* @DecimalMin(value= ,inclusive=) 值必须大于等于value 指定的值
* @Digits(integer= ,fraction=)
*
* @Future 值必须是将来的时间
* @Past 值必须是过去的时间
*
* 此属性必须是数字
* @Max 值必须小于等于value 指定的值,不能注解在字符串类型的属性上
* @Min 值必须大于等于value 指定的值,不能注解在字符串类型的属性上
*/
如果这些校验注解不满要求,还可以添加自定义注解,比如
@Idcard
参考
- Validation in Spring Boot
- Hibernate Validator 校验注解