Javabean非空变量校验工具

摘要 调研java Class getDeclaredFields() 与getFields()的区别,设计请求参数为Javabean时,基于反射机制校验其中非空变量的公共方法。

 

java Class getDeclaredFields() 与getFields()的区别

概述:

(1)getDeclaredFields() 返回Class中所有的字段,包括私有字段;

(2)getFields 只返回公共字段,即由public修饰的字段。

测试之前,请定义一个代表员工的EmployeeDTO类,成员变量访问控制修饰符包括public等,当前,实际定义Javabean的时候,成员变量的控制修饰符是只可以为private的。

public class EmployeeDTO {
    public Integer id;
    private String sex;
    private String name;
    protected String job; // 职位
    public Integer jobNumber;// 工号
    private float salary;

    String phone;
    // 省略get、set方法  
}

测试用例,一个main函数:

public class ValidationTest {

    public static void main(String[] args) {
//        testGetDeclaredFields();
//        System.err.println(" ==================== ");
//        testGetFields();
        validateIsEmpty();
    }

    public static void testGetDeclaredFields() {
        Field[] fields = EmployeeDTO.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            System.out.println(field.getName());
        }
    }

    public static void testGetFields() {
        Field[] fields = EmployeeDTO.class.getFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            System.out.println(field.getName());
        }
    }

    
}

testGetFields ()打印结果:

id
jobNumber

testGetDeclaredFields ()打印结果:

id
sex
name
job
jobNumber
salary
phone

由测试结果可见,上述概述成立。

校验Java bean中非空字段

在ValidationTest中新增如下函数:

public static void validateIsEmpty() {
        EmployeeDTO emp = new EmployeeDTO();
        emp.setId(100);
        emp.setJob(null);
        emp.setJobNumber(100001);
        List<String> checkedFieldNames = new ArrayList<>();
        checkedFieldNames.add("id");
        checkedFieldNames.add("job");
        checkedFieldNames.add("jobNumber");
        try {
            ValidationUtils.checkNotEmpty(emp, checkedFieldNames);
        } catch (Exception e) {
            System.out.println("-----------");
            System.out.println(e.getMessage());
        }
    }

其中,本章节的主角ValidationUtils源码如下:

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

/**
 * @Description 校验工具类
 */
public class ValidationUtils {

    private final static String PIX_GET = "get";

    /**
     * @Description 只校验列表中传入的字段,断言对象中的字段值非空
     * 
     * @param object 待检测对象
     * @param checkedFieldNames 被检查变量
     * @throws Exception 如果被校验字段的值为空,抛出此异常
     */
    public static void checkNotEmpty(Object object, List<String> checkedFieldNames) throws Exception {
        if (null == object) {
            throw new Exception("Param is NULL");
        }
        Class<?> clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        String fieldName = "";
        StringBuilder methodName = null;
        Method method = null;
        for (Field field : fields) {
            fieldName = field.getName();
            if (!hasElement(fieldName, checkedFieldNames)) {
                continue;
            }
            methodName = new StringBuilder(PIX_GET);
            methodName = methodName.append(fieldName.substring(0, 1).toUpperCase())
                    .append(fieldName.substring(1));
            method = clazz.getDeclaredMethod(methodName.toString());
            Object result = method.invoke(object);
            if (null == result || "".equals(result)) {
                throw new Exception("Non-empty field 【".concat(fieldName).concat("】 is empty"));
            }
        }
    }

    /**
     *  检测container数组是否包含element元素
     * 
     * @return boolean,true 包含
     */
    private static boolean hasElement(String element, List<String> containers) {
        if (containers.contains(element)) {
            return true;
        }
        return false;
    }
}

在main函数中调用后,控制台打印如下信息:

Non-empty field 【job】 is empty

 

 

表明校验成功,如果为job赋值为非空,则不再提示此信息。至于其它成员变量,同理可以测试。

所以,在校验实际业务场景中的JavaBean的时候,就无需每次手动校验了。丢给ValidationUtils即可,是不是很方便?

 

posted @ 2018-12-07 09:35  楼兰胡杨  阅读(2344)  评论(0编辑  收藏  举报