3个注解搞定参数及接口版本校验

使用方式:

1.在controller层加上

 校验参数
    //注册保存的校验组:VGroup.save
    @Validator(bean=Register.class,group=VGroup.save)
    //注册发送短信时校验组:VGroup.excutor
    @Validator(bean=Register.class,group=VGroup.excutor)

 校验接口版本号
    @Version(version=1,message="请升级到最新版本")

2.配置拦截器:
    @Override
    public void onInterceptorConfig(Interceptors interceptors) {
        interceptors.add(new ValidatorInterceptor());
    }

3.在不同的实体类上配置校验规则:
    @VRules(rules={
        @VRule(attrName = "mobilePhone", message="手机号码有误", groups = { VGroup.save,VGroup.excutor },  types = { VType.mobilePhone } ),
        @VRule(attrName = "password", message="密码最少为6位字符",  groups = { VGroup.save },  types = { VType.password } ),
        @VRule(attrName = "verifyCode", message="验证码有误",  groups = { VGroup.excutor },  types = { VType.number } ),
        @VRule(attrName = "messageId", message="验证码标识有误",  groups = { VGroup.excutor },  types = { VType.notnull } )
    })
    public class Register implements Serializable{}


具体实现:

/**
 * ------------------------------
 * 数据验证规则
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年5月30日
 * @version 1.0
 */
public interface IVRule {
    /**
     * 校验规则
     */
    public static final Map<String,List<ValidatorRule>> BEAN_VALIDATOT_RULE=new HashMap<String,List<ValidatorRule>>();
    /**
     * 是否初始化校验规则
     */
    public static final Map<String,Boolean> IS_INIT_VALIDATOT_RULE=new HashMap<String,Boolean>();
}
/**<pre>
 * ------------------------------
 * 用于controller层需要验证数据较多时的验证
 * 默认VGroup=VGroup.excutor
 * 默认VRenderType=VRenderType.json
 * ------------------------------
 * </pre>
 * @author wdm(l311576@sina.com)  @date 2018年5月30日
 * @version 1.0
 */
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Validator {
    VGroup group() default VGroup.excutor;
    Class<?> bean();
    String beanName() default "";
    String uri() default "";
    VRenderType render()  default VRenderType.json;
}
/**
 * ------------------------------
 * 用于controller层验证版本号
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年5月30日
 * @version 1.0
 */
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Version {
    String message();
    int version();
}
package com.www.mall.common.validator;

public enum VRenderType {
    json,redirect,render
}
/**
 * ------------------------------
 * 配置一条校验规则
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年7月31日
 * @version 1.0
 */
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface VRule {
    VGroup[] groups() default {VGroup.excutor};
    VType[] types();
    String attrName();
    String message() default "参数错误";
}
/**
 * ------------------------------
 * 校验规则
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年7月31日
 * @version 1.0
 */
@Documented
@Target(ElementType.TYPE)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface VRules {
    VRule[] rules();
}
/**
 * ------------------------------
 * 验证数据类型
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年5月30日
 * @version 1.0
 */
public enum VType {
    /**非空验证**/
    notnull,
    /**非空时验证电子邮箱格式,空表示通过**/
    ne_email,
    /**非空时验证身份证格式,空表示通过**/    
    ne_idcard,
    
    /**验证电子邮箱格式**/
    email,
    /**验证身份证格式**/    
    idcard,
    /**验证日期格式**/    
    date,
    /***手机号验证***/
    mobilePhone,
    /***密码验证***/
    password,    
    /***数字验证***/
    number
}
/**
 * ------------------------------
 * 验证数据规则
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年5月30日
 * @version 1.0
 */
public class ValidatorRule {

    private List<VGroup> vGroups;
    private List<VType> vTypes;
    private String validatorField;
    private String message;
    
    /**
     * 构建一个数据验证规则
     * @param validatorField
     * @param message
     * @param vGroups
     * @param vTypes
     * @return
     */
    public static ValidatorRule bulid(String validatorField,String message,List<VGroup> vGroups,List<VType> vTypes){
        return new ValidatorRule(vGroups,vTypes,validatorField,message);
    }
    
    /**
     * 都需要验证的数据
     * 如:save和update操作时都需要验证这个参数
     * @param validatorGroups
     * @return
     */
    public static List<VGroup> group(VGroup... validatorGroups){
        List<VGroup> list=new ArrayList<VGroup>();
        for (int i = 0; i < validatorGroups.length; i++) {
            list.add(validatorGroups[i]);
        }
        return list;
    }
    
    /**
     * 数据的验证类型
     * @param validatorTypes
     * @return
     */
    public static List<VType> type(VType... validatorTypes){
        List<VType> list=new ArrayList<VType>();
        for (int i = 0; i < validatorTypes.length; i++) {
            list.add(validatorTypes[i]);
        }
        return list;
    }
    
    private ValidatorRule(){}
    private ValidatorRule(List<VGroup> vGroups, List<VType> vTypes, String validatorField,
            String message) {
        super();
        this.vGroups = vGroups;
        this.vTypes = vTypes;
        this.validatorField = validatorField;
        this.message = message;
    }

    public List<VGroup> getValidatorGroups() {
        return vGroups;
    }
    public void setValidatorGroups(List<VGroup> vGroups) {
        this.vGroups = vGroups;
    }
    public List<VType> getValidatorTypes() {
        return vTypes;
    }
    public void setValidatorTypes(List<VType> vTypes) {
        this.vTypes = vTypes;
    }
    public String getValidatorField() {
        return validatorField;
    }
    public void setValidatorField(String validatorField) {
        this.validatorField = validatorField;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    
}

数据校验拦截器

/**
 * ------------------------------
 * 参数验证拦截器
 * ------------------------------
 * @author wdm(l311576@sina.com)  @date 2018年5月31日
 * @version 1.0
 */
public class ValidatorInterceptor implements Interceptor {
    
    @Override
    public void intercept(Invocation inv) {
        Version version=inv.getMethod().getAnnotation(Version.class);
        if(version!=null && !verifyVersion(inv, version)){
            return;
        }
        
        Validator validator = inv.getMethod().getAnnotation(Validator.class);
        if (validator != null && !validate(inv, validator)) {
            return;
        }
        inv.invoke();
    }
    
    private boolean verifyVersion(Invocation inv, Version version) {
        int vers=version.version();
        String message=StringUtils.isBlank(version.message())?"该功能已升级,如要继续使用请升级app到最新版本":version.message();
        Controller controller=inv.getController();
        
        if(vers>-1){
            int verifyVersion = -1;
            String versionStr= controller.getHeader("version");//验证版本号
            if(versionStr!=null){
                try {
                    verifyVersion=Integer.valueOf(versionStr);
                } catch (Exception e) {
                    //版本信息错误  必须是int类型数字
                    e.printStackTrace();
                }
            }
            
            if(verifyVersion<vers){
                renderError( controller,VRenderType.json, "" ,RC.VERSION_FAIL,message);
                return false;
            }
            
        }
        return true;
    }

    /**
     * 验证JSON格式的数据
     * @param inv
     * @param validator
     * @return
     */
    private boolean validate(Invocation inv, Validator validator) {
        VRenderType vRenderType=validator.render();
        VGroup group = validator.group();
        Controller controller=inv.getController();
        Class<?> clazz=validator.bean();
        String validatorBeanName=clazz.getName();

        //初始化校验规则
        initValidatorRule(validatorBeanName, clazz);
        List<ValidatorRule>  list=IVRule.BEAN_VALIDATOT_RULE.get(validatorBeanName);
        
        if (list==null) {//没有验证规则
            return true;
        }
        
        JSONObject jsonObject= json(controller.getPara("param"),controller.getHeader("ploy"));
        String beanName=validator.beanName()+".";
        for (int i = 0; i < list.size(); i++) {//循环每一条数据规则
            ValidatorRule validatorRule=list.get(i);
            List<VGroup> groups = validatorRule.getValidatorGroups();
            if(groups.contains(group)){//包含分组-需要验证该组数据
                String field=beanName+validatorRule.getValidatorField(); 
                String message=validatorRule.getMessage();
                List<VType> validatorRules=validatorRule.getValidatorTypes();
                for (int j = 0; j < validatorRules.size(); j++) {
                    VType vType=validatorRules.get(j);
                    
                    String value =jsonObject==null ?null : jsonObject.getString(field);//controller.getPara(field);
                    
                    if(!validate(vType,value)){
                        renderError(controller,vRenderType, validator.uri(),RC.PARAM_FAIL,message);
                        return false;
                    }
                }
            }
        }
        return true;
    }
    
    /**
     * 初始化验证规则
     * @param isInit
     * @param bean
     */
    private void initValidatorRule(String validatorBeanName,Class<?> clazz) {
        Boolean isInit=IVRule.IS_INIT_VALIDATOT_RULE.get(validatorBeanName);
        if(isInit!=null && isInit){//是否已经初始化
            return;
        }
        VRules vRules=clazz.getAnnotation(VRules.class);
        if(vRules!=null){
            VRule[] rules=vRules.rules();
            if(rules.length>0){
                List<ValidatorRule> validatorRules=new ArrayList<ValidatorRule>();
                for (int i = 0; i < rules.length; i++) {
                    VRule vRule=rules[i];
                    String attrName=vRule.attrName();
                    String message=vRule.message();
                    VGroup[]  validatorGroups=vRule.groups();
                    VType[] validatorTypes=vRule.types();
                    validatorRules.add(ValidatorRule.bulid( attrName, message,ValidatorRule.group(validatorGroups), ValidatorRule.type(validatorTypes)));
                }
                IVRule.BEAN_VALIDATOT_RULE.put(validatorBeanName, validatorRules);
            }
        }
        IVRule.IS_INIT_VALIDATOT_RULE.put(validatorBeanName,true);
    }

    protected JSONObject json(String json,String ploy){
        if(Ploy.ENCRYPT.equals(ploy)){//参数解密
            json=ParamUtil.decryptParam(json);
            if(json==null){
                return null;
            }
        }
        return JSON.parseObject(json);
    }
    
    /**
     * 有需要再追加
     * @param vType
     * @param value
     * @return
     */
    private boolean validate(VType vType, String value) {
        if(vType==VType.notnull){
            return com.xiaoleilu.hutool.lang.Validator.isNotEmpty(value);
        }else if(vType==VType.email){
            return com.xiaoleilu.hutool.lang.Validator.isEmail(value);
        }else if(vType==VType.idcard){
            return IdcardUtil.isvalidCard18(value);
        }else if(vType==VType.ne_email){
            if( com.xiaoleilu.hutool.lang.Validator.isNotEmpty(value)){
                return true;
            }
            return RegexUtils.checkEmail(value);
        }else if(vType==VType.ne_idcard){
            if( com.xiaoleilu.hutool.lang.Validator.isNotEmpty(value)){
                return true;
            }
            return IdcardUtil.isvalidCard18(value);
        }else if(vType==VType.mobilePhone){
            return com.xiaoleilu.hutool.lang.Validator.isMobile(value) && value.length()==11;
        }else if(vType==VType.password){
            return value!=null && value.length()>5;
        }else if(vType==VType.number){
            return com.xiaoleilu.hutool.lang.Validator.isNumber(value);
        }
        
        return true;
    }

    private void renderError(Controller controller,VRenderType vRenderType, String redirect,RC result,String message) {
        if (controller instanceof JbootController) {
            if(vRenderType==VRenderType.json){
                controller.renderJson(Ret.paramFail(message));
            }else if(vRenderType==VRenderType.redirect){
                if(StringUtils.isNotBlank(redirect)){
                    controller.redirect(redirect);
                }
//                 ((JbootController) controller).setFlashAttr("message", message);
//                 ((JbootController) controller).setFlashAttr("result", result);
                controller.renderJson(Ret.result(result.getState(), message));
            }else if(vRenderType==VRenderType.render){
                controller.keepPara();
                if(StringUtils.isNotBlank(redirect)){
                    controller.render(redirect);
                }
//                 ((JbootController) controller).setFlashAttr("message", message);
//                 ((JbootController) controller).setFlashAttr("result", result);
                controller.renderJson(Ret.result(result.getState(), message));
            }else{
                if(StringUtils.isNotBlank(redirect)){
                    controller.redirect(redirect);
                }
                
//                 ((JbootController) controller).setFlashAttr("message", message);
//                 ((JbootController) controller).setFlashAttr("result", result);
                controller.renderJson(Ret.result(result.getState(), message));
            }
        }
    }

}



评论区

himans

2018-08-01 16:28

感谢分享轮子

21th

2018-08-02 14:12

@himans 不用客气O(∩_∩)O~

steven_lhcb_9527

2021-08-05 10:22


使用@Repeatable配置容器注解


/**
* 配置一条校验规则
*/
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(VRules.class)
public @interface VRule {
VType[] types();
String attrName();
String message() default "参数错误";
}

/**
* 校验规则
*/
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface VRules {
VRule[] value();
}

@VRule(attrName = "",types = {},message = "")


@VRule注解在action上即可

热门分享

扫码入社