java 反射结合hibernate-validator 注解校验对象数据合法性

2021/6/25 9:56:45

本文主要是介绍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的切面类里,进行更优雅的数据合法性校验

 



这篇关于java 反射结合hibernate-validator 注解校验对象数据合法性的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程