Bean Validation
簡介
Bean Validation是Java定義的一套基于注解的數(shù)據(jù)校驗(yàn)規(guī)范,目前已經(jīng)從JSR 303的1.0版本升級到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),已經(jīng)經(jīng)歷了三個版本
"數(shù)據(jù)校驗(yàn)"是這個比較常見的工作,在日常的開發(fā)中貫穿于代碼的各個層次,從上層的View層到下底層的數(shù)據(jù)層,為了保證程序的正確運(yùn)行以及數(shù)據(jù)的正確性歧寺,開發(fā)者通常會在不同層次間做數(shù)據(jù)校驗(yàn)而且這些校驗(yàn)通常是重復(fù)的燥狰,為了實(shí)現(xiàn)代碼的復(fù)用性,通常會把校驗(yàn)的邏輯寫在被校驗(yàn)對象上斜筐。
Bean Validation就是為了解決這樣的問題龙致,它定義了一套元數(shù)據(jù)模型和API對JavaBean實(shí)現(xiàn)校驗(yàn),默認(rèn)是以注解作為元數(shù)據(jù)顷链,可以通過XML重寫或者拓展元數(shù)據(jù)目代,通常來說注解的方式可以實(shí)現(xiàn)比較簡單邏輯的校驗(yàn),而復(fù)雜校驗(yàn)就需要通過XML來描述嗤练¢涣耍可以說Bean Validation是JavaBean的一個拓展,也就是說它布局于哪一層的代碼煞抬,不局限于Web應(yīng)用還是端應(yīng)用霜大。
Bean Validation 2.0 關(guān)注點(diǎn)
- 使用Bean Validation的最低Java版本為Java 8
- 支持容器的校驗(yàn),通過
TYPE_USE
類型的注解實(shí)現(xiàn)對容器內(nèi)容的約束:List<@Email String>
- 支持日期/時間的校驗(yàn)革答,@Past和@Future
- 拓展元素?cái)?shù)據(jù):@Email战坤,@NotEmpty,@NotBlank残拐,@Positive途茫, @PositiveOrZero,@Negative溪食,@NegativeOrZero囊卜,@PastOrPresent和@FutureOrPresent
Bean Validation的實(shí)現(xiàn)
Bean Validation在2.0之前有兩個官方認(rèn)可的實(shí)現(xiàn):Hibernate Validator
和Apache BVal
,但如果你想用2.0版本的話错沃,基本上只有Hibernate Validator
栅组,而這里我使用的是Hibernate Validator
,其他實(shí)現(xiàn)不做展開枢析。
使用
安裝依賴
<!--版本自行控制笑窜,這里只是簡單舉例-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b09</version>
</dependency>
Demo-直接使用
- 一個簡單的JavaBean
public class User {
private String name;
private String gender;
@Positive
private int age;
private List<@Email String> emails;
// getter and setter
// ...
}
- 使用Validator校驗(yàn)
User user = new User();
user.setName("seven");
user.setGender("man");
user.setAge(-1);
user.setEmails(Arrays.asList("sevenlin@gmail.com", "sevenlin.com"));
Set<ConstraintViolation<User>> result = Validation.buildDefaultValidatorFactory().getValidator().validate(user);
List<String> message
= result.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue())
.collect(Collectors.toList());
message.forEach(System.out::println);
- 校驗(yàn)結(jié)果
emails[1].<list element> must be a well-formed email address: sevenlin.com
age must be greater than 0: -1
集成到Spring MVC
- 配置
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public Validator getValidator(); {
// ...
}
}
注意,使用Spring MVC 的時候登疗,Spring會默認(rèn)注冊從classpath
下找到的可用Bean Validation,所以如果不需要自定義Validation
- 在Controller中校驗(yàn)請求參數(shù)
使用注解@Valid
和@Validated
實(shí)現(xiàn)對請求參數(shù)的校驗(yàn)
@PostMapping(value = "/create")
@ResponseBody
public ResponseEntity<User> create(@RequestBody @Validated UserForm form) {
User user = userService.create(form);
return ResponseEntity.ok().body(user);
}
- 配置統(tǒng)一校驗(yàn)結(jié)果處理
@ControllerAdvice
public class ValidationResponseAdvice extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(","));
return ResponseEntity.badRequest().body(message);
}
}
常見的元數(shù)據(jù)
meta-data | comment | version |
---|---|---|
@Null | 對象嫌蚤,為空 | Bean Validation 1.0 |
@NotNull | 對象辐益,不為空 | Bean Validation 1.0 |
@AssertTrue | 布爾,為True | Bean Validation 1.0 |
@AssertFalse | 布爾脱吱,為False | Bean Validation 1.0 |
@Min(value) | 數(shù)字智政,最小為value | Bean Validation 1.0 |
@Max(value) | 數(shù)字,最大為value | Bean Validation 1.0 |
@DecimalMin(value) | 數(shù)字箱蝠,最小為value | Bean Validation 1.0 |
@DecimalMax(value) | 數(shù)字续捂,最大為value | Bean Validation 1.0 |
@Size(max, min) | min<=value<=max | Bean Validation 1.0 |
@Digits (integer, fraction) | 數(shù)字垦垂,某個范圍內(nèi) | Bean Validation 1.0 |
@Past | 日期,過去的日期 | Bean Validation 1.0 |
@Future | 日期牙瓢,將來的日期 | Bean Validation 1.0 |
@Pattern(value) | 字符串劫拗,正則校驗(yàn) | Bean Validation 1.0 |
字符串,郵箱類型 | Bean Validation 2.0 | |
@NotEmpty | 集合矾克,不為空 | Bean Validation 2.0 |
@NotBlank | 字符串页慷,不為空字符串 | Bean Validation 2.0 |
@Positive | 數(shù)字,正數(shù) | Bean Validation 2.0 |
@PositiveOrZero | 數(shù)字胁附,正數(shù)或0 | Bean Validation 2.0 |
@Negative | 數(shù)字酒繁,負(fù)數(shù) | Bean Validation 2.0 |
@NegativeOrZero | 數(shù)字,負(fù)數(shù)或0 | Bean Validation 2.0 |
@PastOrPresent | 過去或者現(xiàn)在 | Bean Validation 2.0 |
@FutureOrPresent | 將來或者現(xiàn)在 | Bean Validation 2.0 |
其他
相關(guān)鏈接
- JSR 303: Bean Validation 1.0
- JSR 349: Bean Validation 1.1
- JSR 380: Bean Validation 2.0
- Bean Validation
- Spring MVC