• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

java实现相同属性名称及相似类型的pojo、dto、vo等互转操作

java 搞代码 4年前 (2022-01-09) 25次浏览 已收录 0个评论

已应用于实际项目:

1.thrift对象与dto之间的互转

2.pojo与dto之间的互转

3.pojo与vo之间的互转

1.核心转换工具类,对特别复杂类型不做处理,因为业务场景还未覆盖

package littlehow.convert;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * PojoConvertUtil
 *
 * @author littlehow
 * @time 2017-05-03 16:54
 */
public class PojoConvertUtil {
  private static Logger logger = LoggerFactory.getLogger(PojoConvertUtil.class);
  /**
   * 变量缓存
   */
  private static final Map<String, Map<String, Field>> cacheFields = new ConcurrentHashMap<>();
  private static final Set<Class> basicClass = new HashSet<>();
  static {
    basicClass.add(Integer.class);
    basicClass.add(Character.class);
    basicClass.add(Byte.class);
    basicClass.add(Float.class);
    basicClass.add(Double.class);
    basicClass.add(Boolean.class);
    basicClass.add(Long.class);
    basicClass.add(Short.class);
    basicClass.add(String.class);
    basicClass.add(BigDecimal.class);
  }
  /**
   * 将具有相同属性的类型进行转换
   * @param orig
   * @param <T>
   * @return
   */
  public static <T> T convertPojo(Object orig, Class<T> targetClass) {
    try {
      T target = targetClass.newInstance();
      /** 获取源对象的所有变量 */
      Field[] fields = orig.getClass().getDeclaredFields();
      for (Field field : fields) {
        if (isStatic(field)) continue;
        /** 获取目标方法 */
        Field targetField = getTargetField(targetClass, field.getName());
        if (targetField == null) continue;
        Object value = getFiledValue(field, orig);
        if (value == null) continue;
        Class type1 = field.getType();
        Class type2 = targetField.getType();
        //两个类型是否相同
        boolean sameType = type1.equals(type2);
        if (isBasicType(type1)) {
          if (sameType) setFieldValue(targetField, target, value);
        } else if (value instanceof Map && Map.class.isAssignableFrom(type2)){//对map
          setMap((Map)value, field, targetField, target);
        } else if (value instanceof Set && Set.class.isAssignableFrom(type2)) {//对set
          setCollection((Collection)value, field, targetField, target);
        } else if (value instanceof List && List.class.isAssignableFrom(type2)) {//对list
          setCollection((Collection)value, field, targetField, target);
        } else if (value instanceof Enum && Enum.class.isAssignableFrom(type2)) {//对enum
          setEnum((Enum)value, field, targetField, target);
        } else if (value instanceof java.util.Date &&
            java.util.Date.class.isAssignableFrom(type2)) {//对日期类型,不处理如joda包之类的扩展时间,不处理calendar
          setDate((Date)value, targetField, type2, target, sameType);
        }
      }
      return target;
    } catch (Throwable t) {
      logger.error("转换失败:" + t.getMessage());
      throw new RuntimeException(t.getMessage());
    }
  }
 
  /**
   * 获取字段值
   * @param field
   * @param obj
   * @return
   */
  private static Object getFiledValue(Field field, Object obj) throws IllegalAccessException {
    //获取原有的访问权限
    boolean access = field.isAccessible();
    try {
      //设置可访问的权限
      field.setAccessible(true);
      return field.get(obj);
    } finally {
      //恢复访问权限
      field.setAccessible(access);
    }
  }
 
  /**
   * 设置方法值
   * @param field
   * @param obj
   * @param value
   * @throws IllegalAccessException
   */
  private static void setFieldValue(Field field, Object obj, Object value) throws IllegalAccessException {
    //获取原有的访问权限
    boolean access = field.isAccessible();
    try {
      //设置可访问的权限
      field.setAccessible(true);
      field.set(obj, value);
    } finally {
      //恢复访问权限
      field.setAccessible(access);
    }
  }
 
  /**
   * 转换list
   * @param orig
   * @param targetClass
   * @param <T>
   * @return
   */
  public static <T> List<T> convertPojos(List orig, Class<T> targetClass) {
    List<T> list = new ArrayList<>(orig.size());
    for (Object object : orig) {
      list.add(convertPojo(object, targetClass));
    }
    return list;
  }
 
  /**
   * 设置Map
   * @param value
   * @param origField
   * @param targetField
   * @param targetObject
   * @param <T>
   */
  private static <T> void setMap(Map value, Field origField, Field targetField, T targetObject) throws IllegalAccessException, InstantiationException{
    Type origType = origField.getGenericType();
    Type targetType = targetField.getGenericType();
    if (origType instanceof ParameterizedType && targetType instanceof ParameterizedType) {//泛型类型
      ParameterizedType origParameterizedType = (ParameterizedType)origType;
      Type[] origTypes = origParameterizedType.getActualTypeArguments();
      ParameterizedType targetParam<strong>本文来源gaodai#ma#com搞@@代~&码*网2</strong>eterizedType = (ParameterizedType)targetType;
      Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
      if (origTypes != null && origTypes.length == 2 && targetTypes != null && targetTypes.length == 2) {//正常泛型,查看第二个泛型是否不为基本类型
        Class clazz = (Class)origTypes[1];
        if (!isBasicType(clazz) && !clazz.equals(targetTypes[1])) {//如果不是基本类型并且泛型不一致,则需要继续转换
          Set<Map.Entry> entries = value.entrySet();
          Map targetMap = value.getClass().newInstance();
          for (Map.Entry entry : entries) {
            targetMap.put(entry.getKey(), convertPojo(entry.getValue(), (Class) targetTypes[1]));
          }
          setFieldValue(targetField, targetObject, targetMap);
          return;
        }
      }
    }
    setFieldValue(targetField, targetObject, value);
  }
 
  /**
   * 设置集合
   * @param value
   * @param origField
   * @param targetField
   * @param targetObject
   * @param <T>
   * @throws IllegalAccessException
   * @throws InstantiationException
   */
  private static <T> void setCollection(Collection value, Field origField, Field targetField, T targetObject) throws IllegalAccessException, InstantiationException{
    Type origType = origField.getGenericType();
    Type targetType = targetField.getGenericType();
    if (origType instanceof ParameterizedType && targetType instanceof ParameterizedType) {//泛型类型
      ParameterizedType origParameterizedType = (ParameterizedType)origType;
      Type[] origTypes = origParameterizedType.getActualTypeArguments();
      ParameterizedType targetParameterizedType = (ParameterizedType)targetType;
      Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
      if (origTypes != null && origTypes.length == 1 && targetTypes != null && targetTypes.length == 1) {//正常泛型,查看第二个泛型是否不为基本类型
        Class clazz = (Class)origTypes[0];
        if (!isBasicType(clazz) && !clazz.equals(targetTypes[0])) {//如果不是基本类型并且泛型不一致,则需要继续转换
          Collection collection = value.getClass().newInstance();
          for (Object obj : value) {
            collection.add(convertPojo(obj, (Class) targetTypes[0]));
          }
          setFieldValue(targetField, targetObject, collection);
          return;
        }
      }
    }
    setFieldValue(targetField, targetObject, value);
  }
 
  /**
   * 设置枚举类型
   * @param value
   * @param origField
   * @param targetField
   * @param targetObject
   * @param <T>
   */
  private static <T> void setEnum(Enum value, Field origField, Field targetField, T targetObject) throws Exception{
    if (origField.equals(targetField)) {
      setFieldValue(targetField, targetObject, value);
    } else {
      //枚举类型都具有一个static修饰的valueOf方法
      Method method = targetField.getType().getMethod("valueOf", String.class);
      setFieldValue(targetField, targetObject, method.invoke(null, value.toString()));
    }
  }
 
  /**
   * 设置日期类型
   * @param value
   * @param targetField
   * @param targetFieldType
   * @param targetObject
   * @param <T>
   */
  private static <T> void setDate(Date value, Field targetField, Class targetFieldType, T targetObject, boolean sameType) throws IllegalAccessException {
    Date date = null;
    if (sameType) {
      date = value;
    } else if (targetFieldType.equals(java.sql.Date.class)) {
      date = new java.sql.Date(value.getTime());
    } else if (targetFieldType.equals(java.util.Date.class)) {
      date = new Date(value.getTime());
    } else if (targetFieldType.equals(java.sql.Timestamp.class)) {
      date = new java.sql.Timestamp(value.getTime());
    }
    setFieldValue(targetField, targetObject, date);
  }
 
  /**
   * 获取适配方法
   * @param clazz
   * @param fieldName
   * @return
   */
  public static Field getTargetField(Class clazz, String fieldName) {
    String classKey = clazz.getName();
    Map<String, Field> fieldMap = cacheFields.get(classKey);
    if (fieldMap == null) {
      fieldMap = new HashMap<>();
      Field[] fields = clazz.getDeclaredFields();
      for (Field field : fields) {
        if (isStatic(field)) continue;
        fieldMap.put(field.getName(), field);
      }
      cacheFields.put(classKey, fieldMap);
    }
    return fieldMap.get(fieldName);
  }
 
  /**
   * 确实是否为基础类型
   * @param clazz
   * @return
   */
  public static boolean isBasicType(Class clazz) {
    return clazz.isPrimitive() || basicClass.contains(clazz);
  }
 
  /**
   * 判断变量是否有静态修饰符static
   * @param field
   * @return
   */
  public static boolean isStatic(Field field) {
    return (8 & field.getModifiers()) == 8;
  }
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java实现相同属性名称及相似类型的pojo、dto、vo等互转操作
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址