java利用注解及反射做通用的入参校验

一、原理:

  1、做一个field注解,注解有两个参数:是否必填、toString之后的最大长度

  2、对某个request类(或基类),使用注解标记某个字段的校验详情

  3、通用的static方法,利用反射获取属性的值,并做校验。不通过则抛出特定的异常

 

二、上代码:

异常类:

package com.test;


/**
 * 基础异常
 * @author zyydd
 * @date 2019/1/24 10:33
 * @version 1.0.0
 **/
public class BaseException extends RuntimeException {

    /** 异常码 */
    private String code;
    /** 异常描述 */
    private String desc;

    public BaseException(){

    }

    public String getCode() {
        return code;
    }

    private void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    private void setDesc(String desc) {
        this.desc = desc;
    }

    public BaseException(String code, String desc) {
        this(code, desc, new Throwable(desc));
    }

    public BaseException(String code, String desc, Throwable canse) {
        super(new StringBuilder().append("code=").append(code).append(", desc=").append(desc).toString(), canse);
        this.setCode(code);
        this.setDesc(desc);
    }


    @Override
    public String toString() {
        return new StringBuilder().append(getClass().getName())
                .append("{code=").append(this.getCode())
                .append(", desc=").append(this.getDesc())
                .append("}").toString();
    }
}

 

测试的request类:

package com.test;

/**
 * @author zyydd
 * @date 2019/6/13 18:29
 */
public class TestChildRequest {
    /**
     * name
     */
    @ParameterAttr(isNecessary = true, lengthLimit = 10)
    private String name;

    /**
     * pin
     */
    @ParameterAttr(lengthLimit = 15)
    private String address;

    @ParameterAttr(isNecessary = true)
    private String school;

    private String other;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    public String getOther() {
        return other;
    }

    public void setOther(String other) {
        this.other = other;
    }
}

 

field校验注解类:

package com.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author zyydd
 * @date 2019/6/13 16:52
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterAttr {
    /**
     * 是否必须,默认不必须
     *
     * @return
     */
    boolean isNecessary() default false;

    /**
     * 属性toSring之后,最大长度
     *
     * @return
     */
    int lengthLimit() default 0;

}

 

通用校验工具类及main测试方法:

package com.test;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author zyydd
 * @date 2019/6/13 17:02
 */
public class ParameterCheckUtils {
    private static Logger logger = LoggerFactory.getLogger(ParameterCheckUtils.class);

    public static void commonCheck(Object obj) throws IllegalAccessException {
        if (obj == null) {
            logger.error("obj can not be null!");
            throw new BaseException("9999", "obj can not be null!");
        }

        List<Field> fieldList = new ArrayList<Field>();
        Class clazz = obj.getClass();
        while (!Object.class.equals(clazz)) {
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        for (Field field : fieldList) {
            field.setAccessible(true);
            ParameterAttr attr = field.getAnnotation(ParameterAttr.class);
            if (attr == null) {
                continue;
            }
            Object paramObj = field.get(obj);
            if (attr.isNecessary()) {
                if (paramObj == null || StringUtils.isBlank(paramObj.toString())) {
                    logger.error("class={} field={} can not be null!", obj.getClass().getName(), field.getName());
                    throw new BaseException("9998", "field=" + field.getName() + " can not be null!");
                }
            }
            if (attr.lengthLimit() > 0 && paramObj != null && StringUtils.isNotBlank(paramObj.toString())) {
                if (paramObj.toString().length() > attr.lengthLimit()) {
                    logger.error("class={} field={} length is too long! limit={} but length={}", obj.getClass().getName(), field.getName(), attr.lengthLimit(), paramObj.toString().length());
                    throw new BaseException("9997", "field=" + field.getName() + " length is too long!");
                }
            }
        }
        logger.info("commonCheck success!");
    }

    public static void main(String[] args) throws IllegalAccessException {
        //正常数据
        TestChildRequest request1 = new TestChildRequest();
        request1.setName("王钢蛋");
        request1.setAddress("aabbccddeeaabbc");
        request1.setSchool("北京市智障二中");
        ParameterCheckUtils.commonCheck(request1);

        //为空数据
        try {
            ParameterCheckUtils.commonCheck(null);
        } catch (Exception e) {
            logger.error("error1 ", e);

        }
        //必填没传的数据
        try {
            TestChildRequest request2 = new TestChildRequest();
            request2.setName("王钢蛋");
            request2.setAddress("aabbccddeeaabbc");
            ParameterCheckUtils.commonCheck(request2);
        } catch (Exception e) {
            logger.error("error2 ", e);
        }

        //字段超长的数据
        try {
            TestChildRequest request3 = new TestChildRequest();
            request3.setName("王钢蛋");
            request3.setAddress("aabbccddeeaabbcc");
            request3.setSchool("北京市智障二中");
            ParameterCheckUtils.commonCheck(request3);
        } catch (Exception e) {
            logger.error("error3 ", e);
        }
    }

}

 

执行结果:

 

posted @ 2019-12-10 11:19  振宇要低调  阅读(2421)  评论(0编辑  收藏  举报