美文网首页
Java自定义注解校验参数信息

Java自定义注解校验参数信息

作者: 嬉皮码龙 | 来源:发表于2018-08-27 15:31 被阅读0次

    项目要求

    实际项目中存在诸多场景需要校验入参数据。繁杂的参数校验占据相当部分的代码量,且不友好。
    为便于实际开发写出此注解,切合实际的开发需求,多种场景的数据校验,并抛出自定义的异常信息,便于控制层处理,简化代码。

    对比优势

    1.繁杂的Hibernate校验注解,且不宜定制化开发,不适合多场景数据校验。
    2.自定义注解,配合多场景数据校验,可定制化配置,可扩展,高效,易懂的配置。

    自定义注解

    1. 注解类
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 校验参数注解  可根据需要扩展校验数据的选项,比如值区间max,min,值域
     * @author vinod
     */
    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Validation {
        //校验的属性的类型
        ValidateType value() default ValidateType.TYPE_STRING;
        //配置则根据当前字段校验 默认为空
        String accordField() default "";
        //根据accordField的值校验值 默认为空
        String accordValue() default "";
        //正数校验 默认不校验
        boolean isPositive() default false;
    }
    
    1. 数据类型枚举
    /**
     * 校验枚举
     * @author vinod
     */
    public enum ValidateType {
        TYPE_STRING,
        TYPE_INTEGER,
        TYPE_CHAR,
        TYPE_LONG,
        TYPE_FLOAT,
        TYPE_DOUBLE,
        TYPE_BOOLEAN,
        TYPE_DATE,
        TYPE_LIST,
        TYPE_MAP,
        TYPE_SET,
        TYPE_OBJECT
    }
    

    注解处理类

    1.注解使用: bean中声明属性校验

    public class UserInfo implements Serializable{
        @Validate(ValidateType.TYPE_STRING)
        private String username;
        // 此处则可配置值域为(1,2),需扩展注解
        private Integer sex;       // 1:男 2:女
        // 配置当前字段根据sex=2时才校验非空,
        @Validate(value = ValidateType.TYPE_STRING,accordField = "sex",accordValue = "2")
        private String size;
    }
    

    2.调用方法处理

    // 1.1 校验必填字段
    ValidationHandler.validateParams(req);
    

    3.注解处理类源代码

    import com.vinod.test.util.exception.UserDefineException;
    import com.vinod.test.util.annotation.Validation;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.lang.reflect.Field;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * 仅处理传入object中的Validate注解
     * @author vinod
     */
    public class ValidationHandler {
    
        private static Logger logger = LoggerFactory.getLogger(ValidationHandler.class);
        // 方法重载
        public static void validateParams(Object obj){
            validateParams(obj,null,true);
        }
    
        public static void validateParams(Object obj,boolean accordFlag){
            validateParams(obj,null,accordFlag);
        }
    
        /**
         * 校验参数不为空
         * @param obj 需要校验的对象
         * @param excludeParams 需要排除校验的属性名集合
         * @param accordFlag 根据属性依赖校验
         */
        public static void validateParams(Object obj,Set<String> excludeParams,boolean accordFlag){
            logger.info("xxxx日志记录");
    
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                try {
                    Object value = field.get(obj);
                    // 当前属性在需要排除校验的集合中时,跳过当前字段校验。
                    if(excludeParams!=null&&excludeParams.contains(field.getName())){
                        continue;
                    }
                    Validation annotation = (Validation)field.getAnnotation(Validation.class);
                    //System.out.println("=====----"+annotation+"---> "+field.getName());
                    //注解存在时,则说明当前字段需要校验
                    if(annotation!=null){
                        // 是否根据依据筛选为空属性
                        if(accordFlag){
                            // 根据某字段判别是否为空
                            if(StringUtils.isNotEmpty(annotation.accordField())){
                                Field accordField = obj.getClass().getDeclaredField(annotation.accordField());
                                accordField.setAccessible(true);
                                Object accordValue = accordField.get(obj);
                                // 为空或不等于注解预设值则跳过当前属性的校验
                                if(accordValue==null||!accordValue.toString().equals(annotation.accordValue())){
                                    continue;
                                }
                            }
                        }
                        // 属性值不能为空
                        if(value==null){
                            throw new UserDefineException(field.getName());
                        }
                        checkTypeEnumValue(annotation,field,value,annotation.isPositive());
                    }
                } catch (IllegalAccessException e) {
                    // e.printStackTrace();
                    logger.info("xxxx日志记录");
                   //抛出自定义异常信息
                   throw new UserDefineException(field.getName());
                } catch (NoSuchFieldException e) {
                   logger.info("xxxx日志记录");
                   //抛出自定义异常信息
                   throw new UserDefineException(field.getName());
                }
            }
        }
    
        /**
         * 校验注解配置的属性值
         * @param annotation
         * @param field  
         * @param value
         * @param isPositive
         */
        private static void checkTypeEnumValue(Validation annotation, Field field, Object value,boolean isPositive){
            // 暂值列举几种数据处理,剩余类型处理类似
            switch (annotation.value()){
                case TYPE_STRING:
                    if(StringUtils.isEmpty(value.toString())||"null".equals(value.toString().toLowerCase())){
                        throw new UserDefineException(field.getName());
                    }
                    break;
                case TYPE_LONG:
                    if(0L==(Long)value){
                        throw new UserDefineException(field.getName());
                    }
                    if(isPositive&&(Long)value<0){
                        throw new UserDefineException(field.getName());
                    }
                    break;
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Java自定义注解校验参数信息

          本文链接:https://www.haomeiwen.com/subject/epoziftx.html