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

已应用于实际项目:

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 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);

}

}

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

以上这篇java实现相同属性名称及相似类型的pojo、dto、vo等互转操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 java实现相同属性名称及相似类型的pojo、dto、vo等互转操作 的全部内容, 来源链接: utcz.com/z/339048.html

回到顶部