4 Star 8 Fork 4

任哓东 / kuizii脚手架-基于spring cloud

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
BeanHelper.java 19.59 KB
一键复制 编辑 原始数据 按行查看 历史
package com.kuizii.base.common.utils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import java.beans.PropertyDescriptor;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Clob;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Supplier;
/**
* @author renxiaodong
*/
public class BeanHelper {
static Logger log = LoggerFactory.getLogger(BeanHelper.class);
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String YYYY_MM_DD = "yyyy-MM-dd";
static {
rules = new HashMap<>();
registerConverter(Date.class, new DefaultDateConverter());
registerConverter(LocalDate.class, new DefaultLocalDateConverter());
registerConverter(LocalDateTime.class, new DefaultLocalDateTimeConverter());
registerConverter(Clob.class, new DefaultClobConverter());
registerConverter(String.class, new DefaultStringConverter());
}
static Map<Class, Converter> rules;
public static void registerConverter(Class cls, Converter converter) {
rules.put(cls, converter);
}
public static void deregisterConverter(Class cls, Converter converter) {
rules.remove(cls, converter);
}
public static Converter getConverter(Class cls) {
Converter converter = rules.get(cls);
if (converter == null) {
for (Class keyClz : rules.keySet()) {
if (keyClz.isAssignableFrom(cls)) {
converter = rules.get(keyClz);
rules.put(cls, converter);
break;
}
}
}
return converter;
}
public static class DefaultStringConverter implements Converter {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS);
SimpleDateFormat sdt = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
SimpleDateFormat sd = new SimpleDateFormat(YYYY_MM_DD);
@Override
public <T> T convert(Class<T> targetClass, Object sourceValue) {
if (sourceValue == null) {
return null;
}
try {
if (targetClass == String.class) {
return (T) sourceValue;
} else if (targetClass == Date.class) {
int length = sourceValue.toString().length();
if (length >= YYYY_MM_DD_HH_MM_SS.length()) {
return (T) sdt.parse((String) sourceValue.toString().substring(0, YYYY_MM_DD_HH_MM_SS.length()));
} else if (length >= YYYY_MM_DD.length() && length <= YYYY_MM_DD_HH_MM_SS.length()) {
return (T) sd.parse((String) sourceValue.toString().substring(0, YYYY_MM_DD.length()));
}
} else if (targetClass == LocalDate.class) {
return (T) LocalDate.parse((String) sourceValue, dateTimeFormatter);
} else if (targetClass == LocalDateTime.class) {
return (T) LocalDateTime.parse((String) sourceValue, dateTimeFormatter);
} else {
return ConverterSupport.cast(sourceValue, targetClass);
}
} catch (Exception ex) {
log.warn("转换对象失败", ex);
ex.printStackTrace();
}
return null;
}
}
public static class DefaultDateConverter implements Converter {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public <T> T convert(Class<T> targetClass, Object sourceValue) {
if (sourceValue == null) {
return null;
}
if (targetClass == Date.class) {
return (T) sourceValue;
} else if (targetClass == LocalDate.class) {
Date date = (Date) sourceValue;
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()) //设置当前系统时区
.toLocalDate();
return (T) localDate;
} else if (targetClass == LocalDateTime.class) {
Date d = (Date) sourceValue;
return (T) LocalDateTime.ofInstant(d.toInstant(), ZoneId.systemDefault());
} else if (targetClass == String.class) {
return (T) dateTimeFormatter.format(((Date) sourceValue).toInstant());
}
return null;
}
}
public static class DefaultLocalDateConverter implements Converter {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public <T> T convert(Class<T> targetClass, Object sourceValue) {
if (sourceValue == null) {
return null;
}
LocalDate localDate = (LocalDate) sourceValue;
if (targetClass == Date.class) {
return (T)Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
} else if (targetClass == LocalDate.class) {
return (T) sourceValue;
} else if (targetClass == LocalDateTime.class) {
return (T) LocalDateTime.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth(), 0, 0);
} else if (targetClass == String.class) {
return (T) localDate.format(dateTimeFormatter);
}
return null;
}
}
public static class DefaultLocalDateTimeConverter implements Converter {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public <T> T convert(Class<T> targetClass, Object sourceValue) {
if (sourceValue == null) {
return null;
}
LocalDateTime localDate = (LocalDateTime) sourceValue;
if (targetClass == Date.class) {
return (T) Date.from(localDate.atZone(ZoneId.systemDefault()).toInstant());
} else if (targetClass == LocalDate.class) {
return (T) LocalDate.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth());
} else if (targetClass == LocalDateTime.class) {
return (T) sourceValue;
} else if (targetClass == String.class) {
return (T) localDate.format(dateTimeFormatter);
}
return null;
}
}
public static class DefaultClobConverter implements Converter {
@Override
public <T> T convert(Class<T> targetClass, Object sourceValue) {
if (sourceValue == null || !(sourceValue instanceof Clob)) {
return null;
}
try {
Clob clob = (Clob) sourceValue;
if (targetClass == String.class) {
Reader reader = clob.getCharacterStream();
StringBuilder buf = new StringBuilder();
char[] chars = new char[2048];
for (; ; ) {
int len = reader.read(chars, 0, chars.length);
if (len < 0) {
break;
}
buf.append(chars, 0, len);
}
String text = buf.toString();
reader.close();
return (T) text;
}
return null;
} catch (Exception e) {
throw new RuntimeException("转换 clob 失败", e);
}
}
}
/**
* BeanHelper.copyProperties(xxEntity,XXVO.class)
* 建议采用BeanHelper.copyProperties(xxEntity,XXVO::new) 这种方式性能更好
*
* @param source
* @param clazz
* @param <T>
* @param <S>
* @return
*/
public static <S, T> T copyProperties(S source, Class<T> clazz, String... ignoreProperties) {
T o = null;
if (source == null) {
return null;
} else if (source instanceof List) {
return (T) copyListProperties((List) source, clazz, ignoreProperties);
} else if (source instanceof Map) {
return (T) copyProperties((Map) source, clazz, true, ignoreProperties);
}
try {
o = clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("无法实例化" + clazz + "类型");
}
return copyProperties(source, o, ignoreProperties);
}
/**
* 推荐使用该方法
* BeanHelper.copyProperties(xxEntity,XXVO::new)
*
* @param source
* @param target
* @param ignoreProperties
* @param <T>
* @return
*/
public static <T, S> T copyProperties(S source, Supplier<T> target, String... ignoreProperties) {
if (source == null) {
return null;
} else if (source instanceof List) {
return (T) copyListProperties((List) source, target, ignoreProperties);
} else if (source instanceof Map) {
return (T) copyProperties((Map) source, target, ignoreProperties);
} else {
return copyProperties(source, target.get(), ignoreProperties);
}
}
public static <S, T> T copyProperties(S source, T target, String... ignoreProperties) {
if (source == null) {
return null;
}
Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
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) {
// if (Collection.class.isAssignableFrom(targetPd.getPropertyType()) && Collection.class.isAssignableFrom(sourcePd.getPropertyType())) {
// Collection children = (Collection) sourcePd.getReadMethod().invoke(source);
// for (Object val : children) {
// copyProperties( source, )
// }
// continue;
// System.out.println("不支持属性为List的类型转换");
// }
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null && (ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType()) || rules.containsKey(readMethod.getReturnType()))) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
Converter converter = getConverter(sourcePd.getPropertyType());
if (converter != null) {
value = converter.convert(targetPd.getPropertyType(), value);
}
writeMethod.invoke(target, value);
} catch (Throwable ex) {
throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
return target;
}
/**
* 这个方法效率极低,不要使用 ,建议使用 BeanHelper.copyListProperties
*
* @param obj
* @param clazz
* @param <T>
* @param <Y>
* @return
*/
@Deprecated()
public static <T, Y> List<T> convertList(List<Y> obj, Class<T> clazz) {
if (obj == null) {
return null;
}
List<T> resultList = JSON.parseArray(JSON.toJSONString(obj), clazz);
return resultList;
}
public static <T> Page<T> toPage(IPage<?> pageList, Class<T> clazz) {
if (pageList == null) {
return null;
}
Page<T> destPage = new Page<>();
destPage.setPages(pageList.getPages());
destPage.setSize(pageList.getSize());
destPage.setCurrent(pageList.getCurrent());
destPage.setTotal(pageList.getTotal());
List<T> destList = copyListProperties(pageList.getRecords(), clazz);
destPage.setRecords(destList);
return destPage;
}
public static <S, T> List<T> copyListProperties(List<S> sources, Class<T> cls, String... ignoreProperties) {
return copyListProperties(sources, cls, null, ignoreProperties);
}
public static <S, T> List<T> copyListProperties(List<S> sources, Class<T> cls, ColaBeanUtilsCallBack<S, T> callBack, String... ignoreProperties) {
if (sources == null) {
return null;
}
List<T> list = new ArrayList<>(sources.size());
if (!CollectionUtils.isEmpty(sources) && sources.get(0) instanceof Map) {
for (S m : sources) {
try {
T t = copyProperties((Map<String, Object>) m, cls, true, ignoreProperties);
if (callBack != null) {
// 回调
callBack.callBack(m, t);
}
list.add(t);
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
for (S source : sources) {
T t = null;
try {
t = cls.newInstance();
copyProperties(source, t, ignoreProperties);
if (callBack != null) {
// 回调
callBack.callBack(source, t);
}
list.add(t);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> supplier, String... ignoreProperties) {
return copyListProperties(sources, supplier, null, ignoreProperties);
}
/**
* @author Johnson
* 使用场景:Entity、Bo、Vo层数据的复制,因为BeanUtils.copyProperties只能给目标对象的属性赋值,却不能在List集合下循环赋值,因此添加该方法
* 如:List<AdminEntity> 赋值到 List<AdminVo> ,List<AdminVo>中的 AdminVo 属性都会被赋予到值
* S: 数据源类 ,T: 目标类::new(eg: AdminVo::new)
*/
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> supplier, ColaBeanUtilsCallBack<S, T> callBack, String... ignoreProperties) {
if (sources == null) {
return null;
}
List<T> list = new ArrayList<>(sources.size());
if (!CollectionUtils.isEmpty(sources) && sources.get(0) instanceof Map) {
for (S m : sources) {
T t = copyProperties((Map<String, Object>) m, supplier, true);
if (callBack != null) {
// 回调
callBack.callBack(m, t);
}
list.add(t);
}
return list;
} else {
for (S source : sources) {
T t = copyProperties(source, supplier, ignoreProperties);
if (callBack != null) {
// 回调
callBack.callBack(source, t);
}
list.add(t);
}
return list;
}
}
public static <M> M copyProperties(Map<String, Object> value, Supplier<M> supplier, String... ignoreField) {
return copyProperties(value, supplier, true, ignoreField);
}
/**
* @param value
* @param supplier
* @param cemalCase 是否下划线转cemalCase
* @param <M>
* @return
*/
public static <M> M copyProperties(Map<String, Object> value, Supplier<M> supplier, boolean cemalCase, String... ignoreField) {
M t = supplier.get();
return copyProperties(value, supplier.get(), cemalCase);
}
public static <M> M copyProperties(Map<String, Object> value, Class<M> clz, String... ignoreField) {
return copyProperties(value, clz, true, ignoreField);
}
public static <M> M copyProperties(Map<String, Object> value, Class<M> clz, boolean cemalCase, String... ignoreField) {
M t = null;
try {
t = clz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new FatalBeanException("对象创建失败", e);
}
return copyProperties(value, t, cemalCase);
}
public static <M> M copyProperties(Map<String, Object> value, M target, boolean cemalCase, String... ignoreField) {
M t = target;
if (value == null) {
return null;
}
List<String> ignoreList = Arrays.asList(ignoreField);
PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(t.getClass());
Map copy = new HashMap(value.size());
if (cemalCase) {
value.forEach((key, val) -> {
if (ignoreList.contains(key)) {
} else {
key = key.replaceAll("_", "").replaceAll("-", "").toUpperCase();
copy.put(key, val);
}
});
} else {
copy.putAll(value);
}
for (PropertyDescriptor targetPd : targetPds) {
if (targetPd != null) {
try {
Object o = copy.get(targetPd.getName().toUpperCase(Locale.ROOT));
if (null == o) {
continue;
}
Converter converter = getConverter(o.getClass());
if (converter != null) {
o = converter.convert(targetPd.getPropertyType(), o);
}
Method writeMethod = targetPd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(t, ConverterSupport.cast(o, targetPd.getPropertyType()));
} catch (Exception e) {
throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", e);
}
}
}
return t;
}
@FunctionalInterface
public interface ColaBeanUtilsCallBack<S, T> {
void callBack(S t, T s);
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/freexiaodong/kuizii-framework.git
git@gitee.com:freexiaodong/kuizii-framework.git
freexiaodong
kuizii-framework
kuizii脚手架-基于spring cloud
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891