文章主要记录一下工作中封装的对象转换工具类
public class BeanMapUtil {
private static final Map<String, String> DATE_FORMAT_CACHE = new ConcurrentHashMap<>();
private static final Logger LOGGER = LoggerFactory.getLogger(BeanMapUtil.class);
private BeanMapUtil() {
}
@SuppressWarnings("unchecked")
public static <T> List<T> convertList(List<?> originalList, Class<T> resultType) {
return convertList(originalList, resultType, (String[]) null);
}
@SuppressWarnings("unchecked")
public static <T> List<T> convertList(List<?> originalList, Class<T> resultType,
@Nullable String... ignoreProperties) {
if (CollectionUtils.isEmpty(originalList)) {
return Lists.newArrayList();
}
if (resultType.isAssignableFrom(originalList.get(0).getClass())) {
return (List<T>) originalList;
}
List<T> result = new ArrayList<>(originalList.size());
for (Object o : originalList) {
T newObject = BeanUtils.instantiateClass(resultType);
copyProperties(o, newObject, ignoreProperties);
result.add(newObject);
}
return result;
}
@SuppressWarnings("unchecked")
public static <T> T convertObject(Object source, Class<T> resultType) {
return convertObject(source, resultType, (String[]) null);
}
@SuppressWarnings("unchecked")
public static <T> T convertObject(Object source, Class<T> resultType,
@Nullable String... ignoreProperties) {
if (source == null) {
return null;
}
if (resultType.isAssignableFrom(source.getClass())) {
return (T) source;
}
T result = BeanUtils.instantiateClass(resultType);
copyProperties(source, result, ignoreProperties);
return result;
}
public static void copyProperties(Object source, Object target) {
copyProperties(source, target, (String[]) null);
}
public static <T> T mapToObject(Map<String, Object> map, Class<T> beanClass) {
if (map == null) {
return null;
}
T obj;
try {
obj = beanClass.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
Method setter = property.getWriteMethod();
if (setter != null) {
setter.invoke(obj, map.get(property.getName()));
}
}
} catch (IllegalAccessException | IntrospectionException | InstantiationException | InvocationTargetException e) {
throw new IllegalStateException(
"Could not transform " + map + " to " + beanClass.getName(), e);
}
return obj;
}
@SuppressWarnings("unchecked")
public static Map<String, Object> objectToMap(Object obj) {
if (obj == null) {
return null;
} else if (obj instanceof Map) {
return (Map<String, Object>) obj;
}
Map<String, Object> map = new HashMap<>(32);
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
if (key.compareToIgnoreCase("class") == 0) {
continue;
}
Method getter = property.getReadMethod();
Object value = getter != null ? getter.invoke(obj) : null;
map.put(key, value);
}
} catch (IllegalAccessException | IntrospectionException | InvocationTargetException e) {
throw new IllegalStateException(
"Could not transform " + JSON.toJSONString(obj) + " to map", e);
}
return map;
}
public static void copyProperties(Object source, Object target,
@Nullable String... ignoreProperties) {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> targetClass = target.getClass();
PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(targetClass);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object sourceValue = readMethod.invoke(source);
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
if (sourceValue != null) {
Object targetValue = getTargetValue(targetPd, sourceValue, targetClass);
if (targetValue != null) {
writeMethod.invoke(target, targetValue);
}
}
} catch (Exception ex) {
throw new IllegalStateException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
}
@SuppressWarnings("unchecked")
private static Object getTargetValue(PropertyDescriptor targetPd, Object sourceValue, Class<?> targetClass) throws ParseException {
Object targetValue = sourceValue;
Class<?> targetPropertyType = targetPd.getPropertyType();
Class<?> sourcePropertyType = sourceValue.getClass();
if (!targetPropertyType.isAssignableFrom(sourcePropertyType)) {
if (Date.class.isAssignableFrom(sourcePropertyType) && String.class.isAssignableFrom(targetPropertyType)) {
targetValue = DateFormatUtils.format((Date) sourceValue, getDateFormat(targetPd.getName(), targetClass));
}
else if (String.class.isAssignableFrom(sourcePropertyType) && Date.class.isAssignableFrom(targetPropertyType)) {
targetValue = DateUtils.parseDate((String) sourceValue, getDateFormat(targetPd.getName(), targetClass));
}
else if (IBaseEnum.class.isAssignableFrom(targetPropertyType)) {
targetValue = BaseEnumUtil.getEnumByCode(sourceValue, (Class<? extends IBaseEnum>) targetPropertyType);
}
else if (IBaseEnum.class.isAssignableFrom(sourcePropertyType)) {
IBaseEnum baseEnum = (IBaseEnum) sourceValue;
targetValue = baseEnum.getCode().getClass().isAssignableFrom(targetPropertyType) ? baseEnum.getCode() : baseEnum.getDesc();
}
else if (String.class.isAssignableFrom(targetPropertyType)) {
targetValue = String.valueOf(sourceValue);
}
}
return targetValue;
}
private static String getDateFormat(String targetPropertyName, Class<?> targetClass) {
String key = targetClass.getName() + "-" + targetPropertyName;
return DATE_FORMAT_CACHE.computeIfAbsent(key, o -> {
DateFormat annotation = null;
try {
Field field = targetClass.getDeclaredField(targetPropertyName);
annotation = field.getAnnotation(DateFormat.class);
} catch (NoSuchFieldException e) {
LOGGER.error("no such field", e);
}
return Optional.ofNullable(annotation).map(DateFormat::value).orElse(DateUtil.DEFAULT_DATE_FORMAT);
});
}
}
**枚举工具类BaseEnumUtil **
public class BaseEnumUtil {
private BaseEnumUtil() {
}
public static <T extends IBaseEnum> T getEnumByCode(Object code, Class<T> enumType) {
if (code != null) {
for (T t : enumType.getEnumConstants()) {
if (StringUtils.equals(String.valueOf(t.getCode()), String.valueOf(code))) {
return t;
}
}
}
return null;
}
public static <T extends IBaseEnum> T getEnumByDesc(String desc, Class<T> enumType) {
if (StringUtils.isNotBlank(desc)) {
for (T t : enumType.getEnumConstants()) {
if (t.getDesc().equals(desc)) {
return t;
}
}
}
return null;
}
public static <T extends IBaseEnum> T getEnumByCodeOrDesc(Object code, Class<T> enumType) {
T result = getEnumByCode(code, enumType);
if (result == null) {
result = getEnumByDesc(ObjectUtils.toString(code), enumType);
}
return result;
}
}
@DateFormat注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DateFormat {
String value() default DateUtil.DEFAULT_DATE_FORMAT;
}
IBaseEnum接口
public interface IBaseEnum<T> extends Serializable {
T getCode();
@JsonValue
String getDesc();
}