按字符串顺序解析实体类

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);
	}
}
posted @ 2022-07-05 21:34  dagger9527  阅读(67)  评论(0编辑  收藏  举报