需求:如何将一个类转换成一个Map,同时针对类中的属性有要求,Date类型 需要变成String,YYYY -MM-DD HH:mm:ss 对象需要变成json。如何写一个通用的工具
下面是具体的实现方式
public interface ValueMapper {
String value(Object object);
}
public class JsonValueMapper implements ValueMapper {
@Override
public String value(Object object) {
return JSON.toJSONString(object);
}
}
public class DefaultValueMapper implements ValueMapper{
@Override
public String value(Object o) {
if ( null == o){
return null;
}
if (o instanceof Date){
Date date = (Date)o;
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}else if (o instanceof Money){
Money money = (Money)o;
return money.toString();
} else {
return o.toString();
}
}
}
public class LocalSimpleCache {
private Map<String,Object> cache = new ConcurrentHashMap<String, Object>();
public void put(String key, Object value) {
cache.put(key, value);
}
public Object get(String key) {
return cache.get(key);
}
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface FacadeValue {
String key() default "";
Class<? extends ValueMapper> mapper() default DefaultValueMapper.class;
boolean discardNull() default true;
}
public class FacadeValueAnnotation {
private Map<Field,FacadeValue> fieldToFacadeValue;
public Map<Field, FacadeValue> getFieldToFacadeValue() {
return fieldToFacadeValue;
}
public void setFieldToFacadeValue(Map<Field, FacadeValue> fieldToFacadeValue) {
this.fieldToFacadeValue = fieldToFacadeValue;
}
}
public class FacadeMapper {
private static LocalSimpleCache localSimpleCache=new LocalSimpleCache();
public static Map<String,String> toMap(Object o){
FacadeValueAnnotation facadeValueAnnotation=getFacadeValueAnnotation(o.getClass());
Map<String,String> mapResult = Maps.newHashMap();
facadeValueAnnotation.getFieldToFacadeValue().forEach((k,v)->{
Object object=ReflectionUtils.getField(k, o);
if(object==null){
if(!v.discardNull()){
mapResult.put(v.key(), "");
}
}else{
mapResult.put(v.key(), getValueMapper(v.mapper()).value(object));
}
});
return mapResult;
}
/**
* 获取值转换的map
*
* @param mapperClass
* @return
*/
private static ValueMapper getValueMapper(Class<? extends ValueMapper> mapperClass) {
// 先判断缓存中是否有,如果有直接返回
ValueMapper mapper = (ValueMapper) localSimpleCache
.get(mapperClass.getName());
if (mapper != null) {
return mapper;
} else {
try {
mapper = mapperClass.newInstance();
localSimpleCache.put(mapperClass.getName(), mapper);
return mapper;
} catch (Exception e) {
return null;
}
}
}
private static FacadeValueAnnotation getFacadeValueAnnotation(Class clazz){
FacadeValueAnnotation facadeValueAnnotation=(FacadeValueAnnotation)localSimpleCache.get(clazz.getName());
if(facadeValueAnnotation==null){
facadeValueAnnotation=hardParse(clazz);
localSimpleCache.put(clazz.getName(), facadeValueAnnotation);
}
return facadeValueAnnotation;
}
/**
*
* @param clazz
* @return
*/
private static FacadeValueAnnotation hardParse(Class clazz) {
List<Field> fields = FieldUtils
.getFieldsListWithAnnotation(clazz,FacadeValue.class);
if(!CollectionUtils.isEmpty(fields)){
Map<Field, FacadeValue> result = Maps.newHashMap();
for(Field field:fields){
field.setAccessible(true);
result.put(field, field.getAnnotationsByType(FacadeValue.class)[0]);
}
FacadeValueAnnotation facadeValueAnnotation=new FacadeValueAnnotation();
facadeValueAnnotation.setFieldToFacadeValue(result);
return facadeValueAnnotation;
}
return null;
}
}
public class Person {
@FacadeValue(key="person_name")
private String name;
@FacadeValue(key="person_birthday",mapper=DefaultValueMapper.class)
private Date birthday;
@FacadeValue(key="person_age",mapper=DefaultValueMapper.class)
private String age;
@FacadeValue(key="person_address",mapper=JsonValueMapper.class)
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
public class Address {
@FacadeValue(key="address_street")
private String street;
@FacadeValue(key="address_doorNo")
private String doorNo;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getDoorNo() {
return doorNo;
}
public void setDoorNo(String doorNo) {
this.doorNo = doorNo;
}
}
public class Test {
/**
*
* @param args
*/
public static void main(String[] args) {
Person person=new Person();
Address address=new Address();
address.setDoorNo("111");
address.setStreet("中央大到");
person.setAddress(address);
person.setAge("12");
person.setBirthday(new Date());
person.setName("ysgsk");
System.out.println(FacadeMapper.toMap(person));
}
}