一个校验集合中的对象的某些字段值的唯一性的工具类


package com.eya.util.validate;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.ibatis.reflection.ReflectionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.eya.util.ProCollection;
import com.eya.util.ProString;
import com.eya.util.reflects.ReflectUtils;

/**
 * 验证工具类
 * @create ll
 * @createDate 2016年4月28日 下午3:12:40
 * @update 
 * @updateDate 
 */
public class ValidateUtils {
    /** 日志 */
    private static final Logger LOGGER = LoggerFactory.getLogger(ValidateUtils.class);

    /**
     * 对集合中指定字段的值进行唯一性验证
     * @param list 数据集合
     * @param fields 要验证的字段的名称
     * @return 校验的结果
     * @Author : ll. create at 2016年4月28日 下午3:19:52
     */
    public static Set<String> fieldValueUniqueValidate(List<?> list, String... fields) {
        LOGGER.info("【对集合中指定字段的值进行唯一性验证】");

        Set<String> resultSet = new HashSet<String>();

        if (ProCollection.isEmpty(list)) {
            LOGGER.info("【参数list为空】");
            return resultSet;
        }
        if (ProCollection.isEmpty(fields)) {
            LOGGER.info("【参数fields为空】");
            return resultSet;
        }

        LOGGER.info("【参数】fields = {},list = {}", fields, list.toString());
        // 存储依次解析到集合中某个字段的值
        Set<Object> fieldValueSet = new HashSet<Object>();
        // 字段的值
        Object fieldValue = null;
        for (String fieldName : fields) {
            fieldValueSet.clear();
            for (Object item : list) {
                try {
                    fieldValue = ReflectUtils.getValue(item, fieldName);
                } catch (Exception e) {
                    LOGGER.error("使用反射获取字段的值失败", e);
                    throw new ReflectionException();
                }

                // 两种值为空的情况
                if (fieldValue == null) {
                    continue;
                }
                if (fieldValue instanceof String && ProString.isBlank(String.valueOf(fieldValue))) {
                    continue;
                }

                if (fieldValueSet.contains(fieldValue)) {
                    LOGGER.info("【检测到重复值】fieldValue = {}", fieldValue);
                    resultSet.add(String.valueOf(fieldValue));
                    break;
                }
                fieldValueSet.add(fieldValue);
            }
        }

        return resultSet;

    }
}

另外还用到了一个反射工具类,以前的博客中也写过,这里还是再贴下代码


package com.eya.util.reflects;

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

import org.apache.commons.lang3.StringUtils;

import com.eya.util.ProString;

/**
 * 反射工具类
 * @create ll
 * @createDate 2016年4月14日 上午9:17:51
 * @update 
 * @updateDate
 */
public class ReflectUtils {

    /**
     * 通过字段名从对象或对象的父类中得到字段的值
     * @param object 对象实例
     * @param fieldName 字段名
     * @return 字段对应的值
     * @throws Exception
     * @Author : ll. create at 2016年4月14日 上午9:18:19
     */
    public static Object getValue(Object object, String fieldName) throws Exception {
        if (object == null) {
            return null;
        }
        if (StringUtils.isBlank(fieldName)) {
            return null;
        }
        Field field = null;
        Class<?> clazz = object.getClass();
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(object);
            } catch (Exception e) {
                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。  
                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了  
            }
        }

        return null;
    }

    /**
     * 通过字段名从对象或对象的父类中得到字段的值(调用字典的get方法)
     * @param object 对象实例
     * @param fieldName 字段名
     * @return 字段对应的值
     * @throws Exception
     * @Author : ll. create at 2016年4月14日 上午9:18:19
     */
    public static Object getValueOfGet(Object object, String fieldName) throws Exception {
        if (object == null) {
            return null;
        }
        if (StringUtils.isBlank(fieldName)) {
            return null;
        }
        Field field = null;
        Class<?> clazz = object.getClass();
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);

                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                //获得get方法  
                Method getMethod = pd.getReadMethod();
                //执行get方法返回一个Object
                return getMethod.invoke(object);
            } catch (Exception e) {
                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。  
                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了  
            }
        }

        return null;
    }

    /**
     * 通过字段名从对象或对象的父类中得到字段的值(调用字典的get方法,可以取出复杂的对象的值)
     * @param object 对象实例
     * @param fieldName 字段名
     * @return 字段对应的值
     * @throws Exception
     * @Author : ll. create at 2016年4月14日 上午9:18:19
     */
    public static Object getValueOfGetIncludeObjectFeild(Object object, String fieldName)
                                                                                         throws Exception {

        if (object == null) {
            return null;
        }
        if (StringUtils.isBlank(fieldName)) {
            return null;
        }
        Field field = null;
        Class<?> clazz = object.getClass();
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                if (fieldName.contains(".")) {
                    // 如:operatorUser.name、operatorUser.org.name,递归调用
                    String[] splitFiledName = fieldName.split("\\.");
                    return getValueOfGetIncludeObjectFeild(
                        getValueOfGetIncludeObjectFeild(object, splitFiledName[0]),
                        splitFiledName[1]);
                }
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);

                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                //获得get方法  
                Method getMethod = pd.getReadMethod();
                //执行get方法返回一个Object
                return getMethod.invoke(object);
            } catch (Exception e) {
                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。  
                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了  
            }
        }

        return null;
    }

    /**
     * 根据传入对象重新创建一个对象
     * @param object
     * @return
     * @throws Exception
     * @Author : jk. create at 2016年5月31日 下午3:10:42
     */
    public static Object createSameObject(Object object, boolean createChild) throws Exception {
        Class<?> clazz = object.getClass();
        Object obj = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            fields = clazz.getDeclaredFields();
            for (Field f : fields) {
                f.setAccessible(true);
                if (f.getType().getName().equals("java.util.List")) {
                    if (createChild) {
                        Method method = getReadMethod(f.getName(), clazz);
                        if (method != null)
                            f.set(obj, method.invoke(object));
                    }
                } else {
                    Method method = getReadMethod(f.getName(), clazz);
                    if (method != null)
                        f.set(obj, method.invoke(object));
                }
            }
        }
        return obj;
    }

    private static Method getReadMethod(String name, Class<?> clazz) {
        String methodName = "get" + ProString.upperFirst(name);
        try {
            return clazz.getDeclaredMethod(methodName);
        } catch (NoSuchMethodException | SecurityException e) {
            return null;
        }
    }

}

 

转载于:https://my.oschina.net/simpleton/blog/715742

发布了173 篇原创文章 · 获赞 82 · 访问量 22万+
展开阅读全文
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览