基于点注释的Java嵌套POJO更新
我有一个嵌套的POJO结构,定义如下基于点注释的Java嵌套POJO更新,java,Java,我有一个嵌套的POJO结构,定义如下 public class Employee { private String id; private Personal personal; private Official official; } 我从一个带有点注释的服务中得到更新,例如 id change --> id=100 address change --> personal.address=123 Main Street hourly salary c
public class Employee {
private String id;
private Personal personal;
private Official official;
}
我从一个带有点注释的服务中得到更新,例如
id change --> id=100
address change --> personal.address=123 Main Street
hourly salary change --> official.salary.hourly=100
该POJO结构的深度可能为3-4层。我需要查找这个传入的更改值,并在POJO中更新相应的值。最好的方法是什么?如果要创建允许编辑字段的Java对象。可以使用公共/默认/受保护的访问修饰符指定对象字段。这将使您能够获取和设置诸如
个人.地址
或官方.工资.小时
这种方法通常不受欢迎,因为对象不再被封装,并且欢迎任何调用方法来操作对象。如果这些字段没有用getter和setter封装,那么对象就不再是POJO
public
提供从任何地方访问的功能
default
提供从任何包的访问
protected
提供从包或子类的访问
public class Employee {
public String id;
public Personal personal;
public Official official;
}
public class Personal {
public String fName;
public String lName;
public String address;
}
下面是一种使用反射动态设置字段的快速方法。它肯定不是,也不可能是干净的。如果我是你,我会为此使用脚本引擎(假设这样做是安全的) 如果您使用的是setter(甚至可能不是),那么使用LambaMetafactory可能会导致最快的执行。这是我不太熟悉的东西,所以不能提供更多的信息,只有和。尽管您可能需要关于字段的其他信息(我认为输入验证/过滤需要这些信息)
public class Salary {
private double hourly;
private double monthly;
private double yearly;
}
id change --> id=100
address change --> personal.address=123 Main Street
hourly salary change --> official.salary.hourly=100
public class Employee {
public String id;
public Personal personal;
public Official official;
}
public class Personal {
public String fName;
public String lName;
public String address;
}
private static void setValueAt(Object target, String path, String value)
throws Exception {
String[] fields = path.split("\\.");
if (fields.length > 1) {
setValueAt(readField(target, fields[0]),
path.substring(path.indexOf('.') + 1), value);
return;
}
Field f = target.getClass()
.getDeclaredField(path);
f.setAccessible(true);
f.set(target, parse(value, f.getType())); // cast or convert value first
}
//Example code for converting strings to primitives
private static Object parse(String value, Class<?> type) {
if (String.class.equals(type)) {
return value;
} else if (double.class.equals(type) || Double.class.equals(type)) {
return Long.parseLong(value);
} else if (boolean.class.equals(type) || Boolean.class.equals(type)) {
return Boolean.valueOf(value);
}
return value;// ?
}
private static Object readField(Object from, String field) throws Exception {
Field f = from.getClass()
.getDeclaredField(field);
f.setAccessible(true);
return f.get(from);
}
Employee e = new Employee();
e.setOfficial(new Official());
e.setPersonal(new Personal());
e.getOfficial().setSalary(new Salary());
ObjectMapper mapper = new ObjectMapper();
setValueAt(e, "id", "123");
// {"id":"123","personal":{},"official":{"active":false,"salary":{"hourly":0.0,"monthly":0.0,"yearly":0.0}}}
setValueAt(e, "personal.address", "123 Main Street");
// {"id":"123","personal":{"address":"123 Main Street"},"official":{"active":false,"salary":{"hourly":0.0,"monthly":0.0,"yearly":0.0}}}
setValueAt(e, "official.salary.hourly", "100");
// {"id":"123","personal":{"address":"123 Main Street"},"official":{"active":false,"salary":{"hourly":100.0,"monthly":0.0,"yearly":0.0}}}