zoukankan      html  css  js  c++  java
  • java 反射结合hibernate-validator 注解校验对象数据合法性

        java后台项目经常需要校对象的数据合法性,本文使用java反射与hibernate-validator注解的方式实现通用的对象合法性校验,包括对象中的集合属性中数据合法性校验,很有参考价值

        默认项目为sprint boot,步骤如下:

        1、添加hibernate-validator依赖

        2、根据具体业务需要在Entity类的属性上添加需要的校验注解

        3、对象数据保存前,调用公用的校验方法,方法使用反射与Validator结合的方式,返回校验有错误的信息(可以将该方法放置在AOP切面类中,实现更松耦合的校验与业务方法分离)

                   接着我们来看一下每一步骤的具体代码:

        1、添加hibernate-validator依赖

            <dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    </dependency>

    2、根据具体业务需要在Entity类的属性上添加需要的校验注解
         UserInfo ,UserOrderInfo,其中UserOrderInfo是UserInfo的属性值

    @Data
    @Table(name = "user_info")
    public class UserInfo {
    @Id
    @Column(name = "id")
    @GeneratedValue(generator = "JDBC")
    @Comment(value = "数据库主键")
    private Integer id;

    /**用户编码*/
    @Length(max = 32,message = "用户编码长度不可超过32位")
    private String userCode;

    private List<UserOrderInfo> userOrderInfoList;
    }


    @Data
    @Table(name = "user_order_info")
    public class UserOrderInfo {
    @Id
    @Column(name = "id")
    @GeneratedValue(generator = "JDBC")
    @Comment(value = "数据库主键")
    private Integer id;

    /**用户编码*/
    @Length(max = 32,message = "用户编码长度不可超过32位")
    private String userCode;

    /**订单编码*/
    @Length(max = 64,message = "订单编码长度不可超过64位")
    private String orderCode;

    /**商品名称*/
    private String itemName;
       //以下忽略订单中其他属性
    }    

    3、对象数据保存前,调用公用的校验方法,方法使用反射与Validator结合的方式,返回校验有错误的信息(可以将该方法放置在AOP切面类中,实现更松耦合的校验与业务方法分离)

    例如:this.validateEntity(userInfo);//userInfo中包含基本信息与用户所有订单信息,接下来看下具体校验代码
    //该方法可校验系统中所有配置了hibernate-validator校验属性的对象,并返回所有校验失败的错误提示信息
    private List<String> validateEntity(Object object){
    // List
    <String> errorMessages = new ArrayList(); try { Set constraintViolations = validator.validate(object); Class<?> aClass = object.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); //如果需要校验对象中存在集合或者对象属性,需要继续校验 for(Field field:declaredFields){ field.setAccessible(true); if(field.getGenericType() instanceof ParameterizedType){ ParameterizedType pt = (ParameterizedType) field.getGenericType(); //判断具体类的类型 if (pt.getRawType().equals(List.class)) { List objList = (List) field.get(object); for(Object curObj:objList){ Set constraintViolationsObj = validator.validate(curObj); constraintViolations.addAll(constraintViolationsObj); } } } } if (!constraintViolations.isEmpty()) { return this.extractMessage(constraintViolations); } } catch (ConstraintViolationException | IllegalAccessException | InstantiationException ex) { return errorMessages; } return errorMessages; } /** * 转换Set<ConstraintViolation>为List<message> */ protected List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) { List<String> errorMessages = new ArrayList(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getMessage()); } return errorMessages; }

    以上校验方法可通用,也可以写在AOP的切面类里,进行更优雅的数据合法性校验
  • 相关阅读:
    angular源码分析:angular中$rootscope的实现——scope的一生
    angular源码分析:图解angular的启动流程
    angular源码分析:angular的整个加载流程
    angular源码分析:injector.js文件分析——angular中的依赖注入式如何实现的(续)
    angular源码分析:angular中jqLite的实现——你可以丢掉jQuery了
    第二章:互联网的进化成型
    angular源码分析:angular的源代码目录结构说明
    angular源码分析:angular中各种常用函数,比较省代码的各种小技巧
    angular源码分析:angular中的依赖注入式如何实现的
    【Linux】Shell基础命令、文件软(硬)链接的理解
  • 原文地址:https://www.cnblogs.com/DylanZ/p/14929481.html
Copyright © 2011-2022 走看看