package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author zhangkun
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface FieldOrder {
int value();
}
package domain.entity;
import annotation.FieldOrder;
import java.math.BigDecimal;
public class User {
@FieldOrder(1)
String name;
@FieldOrder(2)
String id;
@FieldOrder(3)
Integer age;
@FieldOrder(4)
String sex;
@FieldOrder(5)
BigDecimal money;
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id='" + id + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", money=" + money +
'}';
}
}
package util;
import annotation.FieldOrder;
import domain.entity.User;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author zhangkun
*/
public class ParseUtil {
public static <T> T parse(String s, Class<T> t) {
try {
T instance = t.newInstance();
Field[] fields = t.getDeclaredFields();
BeanInfo beanInfo = Introspector.getBeanInfo(t);
Map<String, List<PropertyDescriptor>> propertyDescriptorsMap =
Arrays.stream(beanInfo.getPropertyDescriptors()).collect(Collectors.groupingBy(PropertyDescriptor::getName));
HashMap<Integer, Field> map = new HashMap<>();
toMap(fields, map, t);
String[] splits = s.split("\\|");
for (int i = 0; i < splits.length; ++i) {
String value = splits[i];
Field field = map.get(i + 1);
if (field == null) {
throw new RuntimeException("split mapping field not found!");
}
List<PropertyDescriptor> propertyDescriptors = propertyDescriptorsMap.get(field.getName());
if (propertyDescriptors == null || propertyDescriptors.isEmpty()) {
throw new RuntimeException("propertyDescriptors is empty!");
}
PropertyDescriptor descriptor = propertyDescriptors.get(0);
Method setMethod = descriptor.getWriteMethod();
if (setMethod == null) {
throw new RuntimeException(field.getName() + " set method not found!");
}
Class<?> propertyType = descriptor.getPropertyType();
copyFieldValue(instance, setMethod, value, propertyType);
}
return instance;
} catch (InstantiationException | IllegalAccessException |
InvocationTargetException | IntrospectionException e) {
e.printStackTrace();
}
return null;
}
protected static void copyFieldValue(Object obj, Method method, String value, Class<?> fieldType)
throws InvocationTargetException, IllegalAccessException {
String typeName = fieldType.getSimpleName();
switch (typeName) {
case "String":
method.invoke(obj, value);
break;
case "Integer":
method.invoke(obj, Integer.valueOf(value));
break;
case "BigDecimal":
method.invoke(obj, new BigDecimal(value));
break;
default:
throw new RuntimeException(typeName + " field type parser not found!");
}
}
public static String toString(Object obj) {
Class<?> aClass = obj.getClass();
Field[] fields = aClass.getDeclaredFields();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
Map<String, List<PropertyDescriptor>> propertyDescriptorsMap =
Arrays.stream(beanInfo.getPropertyDescriptors())
.collect(Collectors.groupingBy(PropertyDescriptor::getName));
TreeMap<Integer, Field> map = new TreeMap<>();
toMap(fields, map, aClass);
StringBuilder sb = new StringBuilder();
for (Map.Entry<Integer, Field> entry : map.entrySet()) {
Field field = entry.getValue();
List<PropertyDescriptor> propertyDescriptors = propertyDescriptorsMap.get(field.getName());
if (propertyDescriptors == null || propertyDescriptors.isEmpty()) {
throw new RuntimeException("propertyDescriptors is empty!");
}
PropertyDescriptor descriptor = propertyDescriptors.get(0);
Method getMethod = descriptor.getReadMethod();
if (getMethod == null) {
throw new RuntimeException(field.getName() + " get method not found!");
}
Object fieldVal = getMethod.invoke(obj);
if (fieldVal != null) {
sb.append(fieldVal.toString()).append("|");
}
}
return sb.substring(0, sb.length() - 1);
} catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public static void toMap(Field[] fields, Map<Integer, Field> map, Class<?> aClass) {
for (Field field : fields) {
FieldOrder annotation = field.getAnnotation(FieldOrder.class);
if (annotation != null) {
int order = annotation.value();
if (map.containsKey(order)) {
throw new RuntimeException(aClass.getSimpleName() + " FieldOrder value is repeat!");
} else {
map.put(order, field);
}
}
}
}
public static void main(String[] args) {
String s = "张三|aa|19|男|10.887";
User user = parse(s, User.class);
System.out.println(user);
String userStr = toString(user);
System.out.println(userStr);
}
}