Bean Validation (JSR-349) 為 Java 提供標準化參數校驗能力。本文詳細講解 SpringMVC 整合 Hibernate Validator 5.x 全流程:依賴、配置、實體校驗註解、分組校驗、EL 表達式、方法級校驗、自定義校驗器、類級校驗、腳本校驗、跨參數校驗、組合註解、國際化等進階特性。
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.2.4.Final</version></dependency> <dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>2.2.4</version><scope>provided</scope></dependency> <!-- slf4j-api 等 -->
<mvc:annotation-driven validator="validator"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list><value>classpath:messages</value><value>classpath:org/hibernate/validator/ValidationMessages</value></list>
</property>
</bean>
public class User implements Serializable {
@NotNull(message = "{user.id.null}", groups = First.class)
private Long id;
@NotEmpty(message = "{user.name.null}")
@Length(min = 5, max = 20, message = "{user.name.length.illegal}", groups = Second.class)
@Pattern(regexp = "[a-zA-Z]{5,20}", message = "{user.name.illegal}", groups = Second.class)
private String name;
@NotNull(message = "{user.password.null}", groups = {First.class, Second.class})
private String password;
}
user.id.null=用戶編號不能為空
user.name.null=用戶名不能為空
user.name.length.illegal=用戶名長度必須在{min}到{max}之間
user.name.illegal=用戶名必須是字母
user.password.null=密碼不能為空
@Controller
public class UserController {
@RequestMapping("/save")
public String save(@Validated({Second.class}) User user, BindingResult result) {
if (result.hasErrors()) return "error";
return "success";
}
}
| 特性 | 關鍵點 |
|---|---|
| 分組校驗 | 定義標記接口 First, Second;註解 groups 指定;@Validated({Group.class}) 啟用 |
| 分組順序 | @GroupSequence({First.class, Second.class, User.class}) 順序校驗,前組失敗不執行後組 |
| EL 表達式 | 消息中用 ${validatedValue} 獲取輸入值,${min} 獲取註解屬性,支持 ${formatter.format('%04d', min)} |
| 方法級校驗 | 啟用 MethodValidationPostProcessor;Service 方法加 @Validated,參數加校驗註解 |
| 自定義校驗器 | 定義 @Constraint(validatedBy=XxxValidator.class) 註解;實現 ConstraintValidator;支持 Spring 注入 |
| 類級校驗 | 實現 ConstraintValidator<Annotation, Bean>;context.disableDefaultConstraintViolation() + buildConstraintViolationWithTemplate() 自定義錯誤屬性 |
| 腳本校驗 | @ScriptAssert(script="_this.password==_this.confirmation", lang="javascript");自定義 PropertyScriptAssert 指定錯誤屬性 |
| 跨參數校驗 | @CrossParameter + ConstraintValidator<Annotation, Object[]>;@SupportedValidationTarget(ValidationTarget.PARAMETERS) |
| 混合校驗器 | 一個註解同時指定類級與參數級兩個 Validator,validationAppliesTo=IMPLICIT 自動判斷 |
| 組合註解 | 在自定義註解上疊加 @NotNull @Length 等,@Constraint(validatedBy={}) 空實現 |
| 國際化 | LocaleResolver + LocaleChangeInterceptor + 多語言 messages_xx.properties |
提示: Spring Boot 2.x 僅需引入
spring-boot-starter-validation即可自動配置,無需 XML。