前言
- 这几天恰好在弄接口相关东西,发现若是对某个多字段的实体进行验证的话,会写不少麻烦并且冗余的代码,因此学了一下相关验证框架。
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必定要正确,否则像我由于这个点,找了好久的问题。有什么问题能够留言,感谢您耐心看完。