Hibernate-validator校验框架使用教程

前言

  • 这几天恰好在弄接口相关东西,发现若是对某个多字段的实体进行验证的话,会写不少麻烦并且冗余的代码,因此学了一下相关验证框架。

Hibernate-Validation

  • 在各层中重复的校验逻辑既致使了没必要要的资源消耗,还使得逻辑不够单一(每层都夹杂着校验的逻辑),JSR 303 Bean Validation就是在这种背景下产生的一个数据验证的J2EE规范。而咱们这篇文中将要介绍的Hibernate Validator则是JBoss社区开源的一个JSR 303 Bean Validation规范的优秀实践

使用流程

  • 导入maven
<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>
  • 建立存储错误消息的properties文件
notnull=该字段不能为空
  • 在验证的model里面对字段进行验证
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 用在基本类型上

使用方法

  • 1 经过在接口出调用,自动验证
@RequestMapping(value = "/demo")
    public String baseInfoCompany(@RequestParam @Valid Demo demo ,BindingResult result) {
        if(result.hasErrors()){
            //这边对错误消息进行处理
        }
        return "success"
    }
  • 2 经过工具类,主动验证某个实体类
@RequestMapping(value = "/demo")
    public String baseInfoCompany(@RequestParam Demo demo) {
        ValidateUtil.validate(demo);
        return "success"
    }
  • ValidateUtil文件
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必定要正确,否则像我由于这个点,找了好久的问题。有什么问题能够留言,感谢您耐心看完。
相关文章
相关标签/搜索