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

来源:互联网 发布:app网络游戏数据修改 编辑:程序博客网 时间:2024/06/08 13:58

  已应用于实际项目:1.thrift对象与dto之间的互转

                                      2.pojo与dto之间的互转

                                      3.pojo与vo之间的互转


  还是喜欢直接贴代码 csdn code代码地址

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 targetParameterizedType = (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;    }}


下面这个类是便于输出展示的,因为只是用于打印,所以不做效率考虑

package littlehow.convert;import java.lang.reflect.Field;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;/** * SimpleToStringParent * * @author littlehow * @time 2017-05-04 10:40 */public class SimpleToStringParent {    @Override    public String toString() {        try {            StringBuilder stringBuilder = new StringBuilder("{");            Field[] fields = this.getClass().getDeclaredFields();            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            for (Field field : fields) {                Object value = getFiledValue(field, this);                if (value == null) continue;                if (value instanceof Date) {                    //这里也可以直接转为时间戳                    value = dateFormat.format((Date)value);                }                stringBuilder.append(field.getName()).append("=").append(value).append(",");            }            String returnValue = stringBuilder.toString();            if (returnValue.length() > 1) {                returnValue = returnValue.substring(0, returnValue.length() - 1);            }            return this.getClass().getSimpleName() + returnValue + "}";        } catch (Exception e) {            // skip        }        return this.getClass().getSimpleName() + "{}";    }    /**     * 获取属性值     * @param field     * @param obj     * @return     * @throws IllegalAccessException     */    private Object getFiledValue(Field field, Object obj) throws IllegalAccessException {        //获取原有的访问权限        boolean access = field.isAccessible();        try {            //设置可访问的权限            field.setAccessible(true);            return field.get(obj);        } finally {            //恢复访问权限            field.setAccessible(access);        }    }}

测试用的4个pojo

1.产品类

package littlehow.convert.pojo;import littlehow.convert.SimpleToStringParent;import java.util.List;/** * Product * * @author littlehow * @time 2017-05-04 09:15 */public class Product extends SimpleToStringParent {    private Integer productId;    private String generalName;    private String factoryName;    private String unit;    private String specification;    private Integer category;    private List<Item> items;    public Integer getProductId() {        return productId;    }    public void setProductId(Integer productId) {        this.productId = productId;    }    public String getGeneralName() {        return generalName;    }    public void setGeneralName(String generalName) {        this.generalName = generalName;    }    public String getFactoryName() {        return factoryName;    }    public void setFactoryName(String factoryName) {        this.factoryName = factoryName;    }    public String getUnit() {        return unit;    }    public void setUnit(String unit) {        this.unit = unit;    }    public String getSpecification() {        return specification;    }    public void setSpecification(String specification) {        this.specification = specification;    }    public List<Item> getItems() {        return items;    }    public void setItems(List<Item> items) {        this.items = items;    }    public Integer getCategory() {        return category;    }    public void setCategory(Integer category) {        this.category = category;    }}

2.商品类

package littlehow.convert.pojo;import littlehow.convert.SimpleToStringParent;import java.util.Date;import java.util.List;/** * Item * * @author littlehow * @time 2017-05-04 09:15 */public class Item extends SimpleToStringParent {    private Long itemId;    private String itemName;    private Byte status;    private Boolean deleted;    private Date createTime;    private List<Sku> skus;    public Long getItemId() {        return itemId;    }    public void setItemId(Long itemId) {        this.itemId = itemId;    }    public String getItemName() {        return itemName;    }    public void setItemName(String itemName) {        this.itemName = itemName;    }    public Byte getStatus() {        return status;    }    public void setStatus(Byte status) {        this.status = status;    }    public Boolean getDeleted() {        return deleted;    }    public void setDeleted(Boolean deleted) {        this.deleted = deleted;    }    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    public List<Sku> getSkus() {        return skus;    }    public void setSkus(List<Sku> skus) {        this.skus = skus;    }}

3.最小库存单位sku

package littlehow.convert.pojo;import littlehow.convert.SimpleToStringParent;import java.lang.reflect.Field;/** * Sku * * @author littlehow * @time 2017-05-04 09:15 */public class Sku extends SimpleToStringParent {    private Long skuId;    private Byte status;    private Boolean deleted;    private Double price;    private Double promoPrice;    private Integer inventory;    private Integer minBuy;    private Integer blockInventory;    private Color skuColor;    public Long getSkuId() {        return skuId;    }    public void setSkuId(Long skuId) {        this.skuId = skuId;    }    public Byte getStatus() {        return status;    }    public void setStatus(Byte status) {        this.status = status;    }    public Boolean getDeleted() {        return deleted;    }    public void setDeleted(Boolean deleted) {        this.deleted = deleted;    }    public Double getPrice() {        return price;    }    public void setPrice(Double price) {        this.price = price;    }    public Double getPromoPrice() {        return promoPrice;    }    public void setPromoPrice(Double promoPrice) {        this.promoPrice = promoPrice;    }    public Integer getInventory() {        return inventory;    }    public void setInventory(Integer inventory) {        this.inventory = inventory;    }    public Integer getMinBuy() {        return minBuy;    }    public void setMinBuy(Integer minBuy) {        this.minBuy = minBuy;    }    public Integer getBlockInventory() {        return blockInventory;    }    public void setBlockInventory(Integer blockInventory) {        this.blockInventory = blockInventory;    }    public Color getSkuColor() {        return skuColor;    }    public void setSkuColor(Color skuColor) {        this.skuColor = skuColor;    }}

4.属性枚举

package littlehow.convert.pojo;/** * Color * * @author littlehow * @time 2017-05-04 09:21 */public enum Color {    BLACK(1),    RED(2),    BLUE(3),    GREEN(4);    public final int value;    Color(int value) {        this.value = value;    }    public static Color valueOf(int value) {        switch (value) {            case 1 : return BLACK;            case 2 : return RED;            case 3 : return BLUE;            case 4 : return GREEN;            default : throw new IllegalArgumentException(value + " is not a enum value");        }    }}


转换用的dto,当然也可以将dto作为转换源

1.产品dto

package littlehow.convert.dto;import littlehow.convert.SimpleToStringParent;import littlehow.convert.pojo.Item;import java.util.List;/** * ProductDto * * @author littlehow * @time 2017-05-04 09:16 */public class ProductDto extends SimpleToStringParent {    private Integer productId;    private String generalName;    private String factoryName;    private String unit;    private String specification;    private Integer category;    private List<ItemDto> items;    public Integer getProductId() {        return productId;    }    public void setProductId(Integer productId) {        this.productId = productId;    }    public String getGeneralName() {        return generalName;    }    public void setGeneralName(String generalName) {        this.generalName = generalName;    }    public String getFactoryName() {        return factoryName;    }    public void setFactoryName(String factoryName) {        this.factoryName = factoryName;    }    public String getUnit() {        return unit;    }    public void setUnit(String unit) {        this.unit = unit;    }    public String getSpecification() {        return specification;    }    public void setSpecification(String specification) {        this.specification = specification;    }    public List<ItemDto> getItems() {        return items;    }    public void setItems(List<ItemDto> items) {        this.items = items;    }    public Integer getCategory() {        return category;    }    public void setCategory(Integer category) {        this.category = category;    }}

2.商品dto

package littlehow.convert.dto;import littlehow.convert.SimpleToStringParent;import littlehow.convert.pojo.Sku;import java.util.Date;import java.util.List;/** * ItemDto * * @author littlehow * @time 2017-05-04 09:16 */public class ItemDto extends SimpleToStringParent {    private Integer itemId;    private String itemName;    private Byte status;    private Boolean deleted;    private Date createTime;    private List<SkuDto> skus;    public Integer getItemId() {        return itemId;    }    public void setItemId(Integer itemId) {        this.itemId = itemId;    }    public String getItemName() {        return itemName;    }    public void setItemName(String itemName) {        this.itemName = itemName;    }    public Byte getStatus() {        return status;    }    public void setStatus(Byte status) {        this.status = status;    }    public Boolean getDeleted() {        return deleted;    }    public void setDeleted(Boolean deleted) {        this.deleted = deleted;    }    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    public List<SkuDto> getSkus() {        return skus;    }    public void setSkus(List<SkuDto> skus) {        this.skus = skus;    }}

3.skudto

package littlehow.convert.dto;import littlehow.convert.SimpleToStringParent;import littlehow.convert.pojo.Color;/** * SkuDto * * @author littlehow * @time 2017-05-04 09:16 */public class SkuDto extends SimpleToStringParent {    private Long skuId;    private Byte status;    private Boolean deleted;    private Double price;    private Double promoPrice;    private Integer inventory;    private Integer minBuy;    private Integer blockInventory;    private ColorDto skuColor;    public Long getSkuId() {        return skuId;    }    public void setSkuId(Long skuId) {        this.skuId = skuId;    }    public Byte getStatus() {        return status;    }    public void setStatus(Byte status) {        this.status = status;    }    public Boolean getDeleted() {        return deleted;    }    public void setDeleted(Boolean deleted) {        this.deleted = deleted;    }    public Double getPrice() {        return price;    }    public void setPrice(Double price) {        this.price = price;    }    public Double getPromoPrice() {        return promoPrice;    }    public void setPromoPrice(Double promoPrice) {        this.promoPrice = promoPrice;    }    public Integer getInventory() {        return inventory;    }    public void setInventory(Integer inventory) {        this.inventory = inventory;    }    public Integer getMinBuy() {        return minBuy;    }    public void setMinBuy(Integer minBuy) {        this.minBuy = minBuy;    }    public Integer getBlockInventory() {        return blockInventory;    }    public void setBlockInventory(Integer blockInventory) {        this.blockInventory = blockInventory;    }    public ColorDto getSkuColor() {        return skuColor;    }    public void setSkuColor(ColorDto skuColor) {        this.skuColor = skuColor;    }}

4.颜色属性

package littlehow.convert.dto;/** * ColorDto * * @author littlehow * @time 2017-05-04 09:21 */public enum ColorDto {    BLACK(1),    RED(2),    BLUE(3),    GREEN(4);    public final int value;    ColorDto(int value) {        this.value = value;    }    public static ColorDto valueOf(int value) {        switch (value) {            case 1 : return BLACK;            case 2 : return RED;            case 3 : return BLUE;            case 4 : return GREEN;            default : throw new IllegalArgumentException(value + " is not a enum value");        }    }}


测试类,简单的做了一下输出查看

package littlehow.convert.test;import littlehow.convert.PojoConvertUtil;import littlehow.convert.dto.ItemDto;import littlehow.convert.dto.ProductDto;import littlehow.convert.dto.SkuDto;import littlehow.convert.pojo.Color;import littlehow.convert.pojo.Item;import littlehow.convert.pojo.Product;import littlehow.convert.pojo.Sku;import org.junit.Before;import org.junit.Test;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * TransTest * * @author littlehow * @time 2017-05-04 10:44 */public class TransTest {    private Product product;    @Before    public void init() {        product = new Product();        product.setCategory(123);        product.setFactoryName("littlehow's shop");        product.setGeneralName("littlehow's product");        product.setProductId(1);        product.setSpecification("16*2u");        product.setUnit("box");        List<Item> items = new ArrayList<>();        for (int i=1; i<=5; i++) {            Item item = new Item();            item.setCreateTime(new Date());            item.setDeleted(i % 3 == 0);            item.setItemId((long) i);            item.setItemName("littlehow's " + i + "th item");            item.setStatus((byte) (i % 4));            List<Sku> skus = new ArrayList<>();            for (int j=1; j<=i; j++) {                Sku sku = new Sku();                sku.setSkuId((long)(j * (i + 5) * 3));                sku.setStatus((byte) 1);                sku.setDeleted(false);                sku.setBlockInventory(5);                sku.setInventory(j * 100);                sku.setMinBuy(j * 5);                sku.setPrice(Double.valueOf(j * 103));                sku.setPromoPrice(Double.valueOf(j * 101));                sku.setSkuColor(Color.valueOf(j % 4 + 1));                skus.add(sku);            }            item.setSkus(skus);            items.add(item);        }        product.setItems(items);    }    @Test    public void test() {        System.out.println(product);//正常输出        System.out.println("========================");        ProductDto productDto = PojoConvertUtil.convertPojo(product, ProductDto.class);        System.out.println(productDto);//正常输出,证明转换正常        System.out.println("=========================");        List<Item> items = product.getItems();        List<ItemDto> itemDtos = PojoConvertUtil.convertPojos(items, ItemDto.class);        System.out.println(itemDtos);//正常输出,数组转换成功    }    @Test    public void test1() {        Sku sku = product.getItems().get(0).getSkus().get(0);        System.out.println(sku);//正常输出        System.out.println("=========================");        SkuDto skuDto = PojoConvertUtil.convertPojo(sku, SkuDto.class);        System.out.println(skuDto);    }}

能快速完成基础类之间的互转

工作笔记

  littlehow 于2017/5/4


1 0
原创粉丝点击