Java实现大字段转对象-对象转大字段
编写转化所需注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface BankAPIField {
/**
* 长度
*/
int length() default -1;
}
编写对象实体
//父类
@Data
public class AbstractDto {
//length 表示此属性所占大字段的长度
@BankAPIField(length = 1)
private String base;
@BankAPIField(length = 15)
private String test;
}
//子类
@Data
public class CreateUserDto extends AbstractDto {
@BankAPIField(length = 10)
private String name;
@BankAPIField(length = 18)
private String identity;
@BankAPIField(length = 11)
private String mobile;
@BankAPIField(length = 5)
private String age;
}
转化工具类
import com.example.mylearn.annotation.BankAPIField;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Slf4j
public class ByteRangeSerializer {
public static <T> String serialize(T t) {
return serialize(t,Collections.emptyList());
}
public static <T> String serialize(T t,List<String> list) {
Field[] allFields = ReflectionUtile.getAllFields(t.getClass());
final String[] largeField = new String[1];
largeField[0]="";
Arrays.stream(allFields)
.filter(field -> field.isAnnotationPresent(BankAPIField.class))
.filter(field -> !list.contains(field.getName()))
.peek(field -> field.setAccessible(true))
.forEach(field -> {
try {
BankAPIField bankField = field.getAnnotation(BankAPIField.class);
String value = (String) field.get(t);
String format = String.format("%-" + bankField.length() + "s", value);
largeField[0] = largeField[0] +format;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
});
return largeField[0];
}
public static <T> T deserialize(String data,Class<T> clz) {
return deserialize(data,clz,Collections.emptyList());
}
public static <T> T deserialize(String data,Class<T> clz,List<String> list) {
Field[] allFields = ReflectionUtile.getAllFields(clz);
Method[] allMethods = ReflectionUtile.getAllMethods(clz);
T obj = null;
try {
obj = clz.newInstance();
}catch (Exception ignored){
}
final String[] subDate = {data};
T finalObj = obj;
Arrays.stream(allFields)
.filter(field -> field.isAnnotationPresent(BankAPIField.class))
.filter(field -> !list.contains(field.getName()))
.peek(field -> field.setAccessible(true))
.forEach(field -> {
BankAPIField bankField = field.getAnnotation(BankAPIField.class);
String filedValue = subDate[0].substring(0, bankField.length()).trim();
newInstance(allMethods,finalObj,field,filedValue);
subDate[0] = subDate[0].substring(bankField.length());
});
return finalObj;
}
private static <T> void newInstance(Method[] allMethods,T obj,Field field,String filedValue){
for (Method allMethod : allMethods) {
if(allMethod.getName().equals(ReflectionUtile.getSetMethodName(field))){
try {
allMethod.invoke(obj,filedValue);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
public static void main(String[] args) {
//前后端必须定好字段长度按注解中的长度来,否则转大字段时就会不准确
CreateUserDto createUserDto = new CreateUserDto();
createUserDto.setAge("22");
createUserDto.setName("张三丰");
createUserDto.setMobile("13456789876");
createUserDto.setIdentity("1");
//赋值父类属性
createUserDto.setBase("2");
createUserDto.setTest("test");
//将参数格式化成一个大字段
String serialize = serialize(createUserDto);
//将大字段解析成对象
CreateUserDto deserialize = deserialize(serialize,CreateUserDto.class);
//生成的大字段必须去除某个属性时使用此方法
String serialize1 = serialize(createUserDto, Lists.newArrayList("test"));
//生成对象时必须去除某个属性时使用
CreateUserDto deserialize1 = deserialize(serialize1, CreateUserDto.class,Lists.newArrayList("test"));
//将对象转化成json返回
System.out.println(JSONUtil.toJsonStr(deserialize));
System.out.println(JSONUtil.toJsonStr(deserialize1));
}
}
反射工具类
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ReflectionUtile {
/**
* 获取类的所有属性
*/
public static Field[] getAllFields(final Class<?> cls) {
final List<Field> allFieldsList = getAllFieldsList(cls);
return allFieldsList.toArray(new Field[0]);
}
public static List<Field> getAllFieldsList(final Class<?> cls) {
Validate.isTrue(cls != null, "The class must not be null");
List<List<Field>> allFieldsList = new ArrayList<>();
Class<?> currentClass = cls;
while (currentClass != null) {
List<Field> allFields = new ArrayList<>();
final Field[] declaredFields = currentClass.getDeclaredFields();
Collections.addAll(allFields, declaredFields);
currentClass = currentClass.getSuperclass();
allFieldsList.add(allFields);
}
Collections.reverse(allFieldsList);
List<Field> allFields = new ArrayList<>();
for (List<Field> fields : allFieldsList) {
allFields.addAll(fields);
}
return allFields;
}
/**
* 获取类的所有方法
*/
public static Method[] getAllMethods(final Class<?> cls) {
final List<Method> allMethodsList = getAllMethodsList(cls);
return allMethodsList.toArray(new Method[0]);
}
public static List<Method> getAllMethodsList(final Class<?> cls) {
Validate.isTrue(cls != null, "The class must not be null");
List<List<Method>> allMethodsList = new ArrayList<>();
Class<?> currentClass = cls;
while (currentClass != null) {
List<Method> allMethods = new ArrayList<>();
final Method[] declaredMethods = currentClass.getDeclaredMethods();
Collections.addAll(allMethods, declaredMethods);
currentClass = currentClass.getSuperclass();
allMethodsList.add(allMethods);
}
Collections.reverse(allMethodsList);
List<Method> allMethods = new ArrayList<>();
for (List<Method> method : allMethodsList) {
allMethods.addAll(method);
}
return allMethods;
}
public static String getSetMethodName(Field field){
return "set" + StringUtils.capitalize(field.getName());
}
public static String getGetMethodName(Field field){
return "get" + StringUtils.capitalize(field.getName());
}
}