前言
- 這幾天恰好在弄接口相關東西,發現若是對某個多字段的實體進行驗證的話,會寫不少麻煩並且冗餘的代碼,因此學了一下相關驗證框架。
Hibernate-Validation
- 在各層中重複的校驗邏輯既致使了沒必要要的資源消耗,還使得邏輯不夠單一(每層都夾雜着校驗的邏輯),JSR 303 Bean Validation就是在這種背景下產生的一個數據驗證的J2EE規範。而咱們這篇文中將要介紹的Hibernate Validator則是JBoss社區開源的一個JSR 303 Bean Validation規範的優秀實踐
使用流程
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.4.Final</version>
</dependency>
<mvc:annotation-driven validator="validator"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<!-- 校驗錯誤信息配置文件 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 資源文件名 -->
<property name="basename" value="classpath:validationMessages"/>
<!-- 對資源文件內容緩存時間,單位秒 -->
<property name="fileEncodings" value="GBK"/>
<property name="defaultEncoding" value="GBK"/>
<property name="cacheSeconds" value="120"/>
</bean>
notnull=該字段不能爲空
public class Demo implements Serializable {
private static final long serialVersionUID = 1L;
@NotBlank(message = "{notnull}")
private String name;
@NotEmpty(message = "{notnull}")
private List<String> address;
@NotNull(message = "{notnull}")
private int address;
}
- 注意:
- @NotEmpty 用在集合類上面
- @NotBlank 用在String上面
- @NotNull 用在基本類型上
使用方法
@RequestMapping(value = "/demo")
public String baseInfoCompany(@RequestParam @Valid Demo demo ,BindingResult result) {
if(result.hasErrors()){
//這邊對錯誤消息進行處理
}
return "success"
}
@RequestMapping(value = "/demo")
public String baseInfoCompany(@RequestParam Demo demo) {
ValidateUtil.validate(demo);
return "success"
}
public class ValidateUtil {
public static <T> void validate(T obj) {
LocalValidatorFactoryBean validator = (LocalValidatorFactoryBean) SpringContextHolder.getBean("validator");//這邊獲取spring已經實例化的驗證器便可,即剛纔配置文件裏配置驗證器id
Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
//拋出檢驗異常
Iterator<ConstraintViolation<T>> iter = constraintViolations.iterator();
while (iter.hasNext()) {
ConstraintViolation<T> error = iter.next();
StringBuffer buffer = new StringBuffer().append("[")
.append(error.getPropertyPath().toString()).append("]")
.append(error.getMessage());
throw new IllegalArgumentException(buffer.toString());
}
}
}
//這個定義要捕捉的異常類
@ExceptionHandler({IllegalArgumentException.class})
@ResponseBody
public RespBean runTimeException(HttpServletRequest request, IllegalArgumentException e) {
String uri = request.getRequestURI();
LOGGER.error("[" + uri + "]捕獲非法異常{}", e.getMessage(), e);
return ErrRespBean.newInstance(ReturnConsts.ERROR_EXCEPTION, e.getMessage());
}
後語
- 千萬注意實體類裏註解引用的message引用properties的key必定要正確,否則像我由於這個點,找了好久的問題。有什麼問題能夠留言,感謝您耐心看完。