Spring Web項目中需要校驗參數的正確性,JSR 303是其規(guī)范,
hibernate-validator是該規(guī)范的一個實現,使用他可以實現統一的參數校驗
- Java Bean Validation的初步使用
- Java Bean Validation自定義注解
- Java Bean Validation分組校驗
- Java Bean Validation校驗@PathVariable和@RequestParam
添加依賴
因為在Spring Boot中默認已經包含了Hibernate Validator,所以不需要再引入額外的Jar包
配置規(guī)則
@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等規(guī)則都是在字段不為Null的時候校驗,如果字段為Null,則不使用這種規(guī)則。如果一定要滿足,則還需要添加規(guī)則@NotNull
Controller中校驗規(guī)則
- 添加注解
@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<String> 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 <T> WebResult<T> handleValidationExceptions(
MethodArgumentNotValidException ex) {
WebResult<T> 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<ConstraintViolation<Person>> violationSet = validator.validate(person);
for (ConstraintViolation<Person> violation : violationSet) {
System.out.println(violation.getMessage());
}
規(guī)則注解列表
/**
* 認識一些校驗注解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