自定义注解非空判断

  因业务需求,要给为null的属性一个默认值,用java代码判断非常繁琐,所以我尝试使用自定义注解来对对象中的属性判断值并给默认值。

首先创建一个自定义注解:  

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

/**
 * @description: 自定义注解->用来校验参数是否为null,如果为null,则根据数据类型不同给不同的默认值
 * @author: Mr.Wang
 * @create: 2019-05-17 14:00
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamsCheck {

    boolean require() default true;
}

而后创建一个相关业务实体类的父类,然后将需要用到上面注解的实体继承该父类

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @description: 实体父类 用于实现自定义注解
 * @author: Mr.Wang
 * @create: 2019-05-17 14:00
 **/
@Slf4j
public class BaseEntity {

    /**
     * 判断是否标记ParamsRequired 注解,如果标记,则做判空处理并给出默认值
     */
    public void validate() {
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ParamsCheck.class)) {
                ParamsCheck paramsCheck = field.getAnnotation(ParamsCheck.class);
                if (paramsCheck.require()) {
                    // 判断数据类型为String integer date
                    if (field.getGenericType().toString().equals("class java.lang.String") ||
                            field.getGenericType().toString().equals("class java.lang.Integer")) {
                        try {
                            // 得到当前属性的get方法
                            Method getter = this.getClass().getMethod("get" + getMethodName(field.getName()));
                            // 调用get方法获得属性值
                            String value = (String) getter.invoke(this);
                            // 判断属性值是否为null
                            if (null == value) {
                                log.info("param {} is null , Please check.", field.getName());
                                if (field.getGenericType().toString().equals("class java.lang.String")) {
                                    Method setString = this.getClass().getMethod("set" + getMethodName(field.getName()), String.class);
                                    // set一个空串
                                    setString.invoke(this, "");
                                } else if (field.getGenericType().toString().equals("class java.lang.Integer")) {
                                    Method setInteger = this.getClass().getMethod("set" + getMethodName(field.getName()), Integer.class);
                                    // set 0
                                    setInteger.invoke(this, 1);
                                }
                            }
                        } catch (Exception e) {
                            log.info("An exception has occurred with the current custom annotation for ParamsCheck!!!", e);
                        }

                    }
                }
            }
        }
    }

    /**
     * 为了组成get方法(高效)
     *
     * @param fieldName 当前字段名
     * @return 将当前字段名的首字母大写后返回
     */
    private String getMethodName(String fieldName) throws Exception {
        byte[] items = fieldName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }

}

   

使用时要在继承该父类的实体属性上加上该注解:

    @ParamsCheck
    private String carLoginTimeStr;

然后在需要做属性判空的程序入口下调用validate()方法即可:

Student student = new Student();
student.validate();

思考:其实最开始设计此处的时候我想要AOP的方式来做,但是因为业务的关系,当前属性并不是在所有的时候都需要进行判断。所以在父类方法中加入了validate方法而不是用切面的形式来做。感兴趣的同学可以尝试使用AOP的方式实现以上功能,这样对于技术的理解也更加深刻。

发布了36 篇原创文章 · 获赞 46 · 访问量 7872

猜你喜欢

转载自blog.csdn.net/weixin_41860630/article/details/90294755