Java 使Gson行为依赖于深度
有没有一种合理的方法使Gson处理嵌套对象的方式不同于顶级对象?要序列化的对象是实体,它们都有一个Java 使Gson行为依赖于深度,java,serialization,gson,Java,Serialization,Gson,有没有一种合理的方法使Gson处理嵌套对象的方式不同于顶级对象?要序列化的对象是实体,它们都有一个id。嵌套实体应替换为其id(以缩短输出并可能避免无休止的递归) 假设有一个 @AllArgsConstructor class User { int id; String name; User parent; } 我执行 User grampa = new User(3, "Grampa", null); User homer = new User(2, "Homer",
id
。嵌套实体应替换为其id
(以缩短输出并可能避免无休止的递归)
假设有一个
@AllArgsConstructor class User {
int id;
String name;
User parent;
}
我执行
User grampa = new User(3, "Grampa", null);
User homer = new User(2, "Homer", grampa);
User bart = new User(1, "Bart", homer);
序列化bart
时得到的结果是
{
id: 1,
name: "Bart",
father: {
id: 2,
name: "Homer",
father: {
id: 3,
name: "Grampa"
}
}
}
这比我需要的多得多。实际上,我从来不想序列化嵌套实体,它们的id
s已经足够好了
使用全局线程局部变量hack和TypeAdapterFactory
{
id: 1,
name: "Bart",
father: 2,
}
这正是我想要的。我更喜欢fatherId
而不是father
,而且我当然更喜欢一些不太粗糙的东西,而不是全局变量
我不想创建一个DAO,反射性地扫描对象,或者类似地扫描对象(那么我可以自己完成整个序列化,不是吗?)。我认为这为“更理智”的方法指明了方向。创建一个TypeAdapter
工厂,它封装状态并返回引用该状态的内部类TypeAdapter
实例,如下所示:
public class UserTypeAdapterFactory {
private Set<Integer> serializedUsers = new HashSet<>();
public JsonSerializer<User> getTypeAdapter() {
return (user, type, context) -> {
JsonObject el = new JsonObject();
el.addProperty("id", user.getId());
el.addProperty("name", user.getName());
if(user.getFather() != null) {
JsonArray els = new JsonArray();
int fatherId = user.getFather().getId();
if(!serializedUsers.contains(fatherId)) {
JsonElement father = context.serialize(user.getFather());
if (father.isJsonArray()) {
els.addAll(father.getAsJsonArray());
} else {
els.add(father);
}
serializedUsers.add(fatherId);
}
el.addProperty("fatherId", fatherId);
els.add(el);
return els;
} else {
return el;
}
};
}
}
Gson gson = new GsonBuilder()
.registerTypeAdapter(
User.class,
new UserTypeAdapterFactory().getTypeAdapter())
.build();
System.out.println(gson.toJson(
new User(1, "Bart", new User(2, "Homer", new User(3, "Grampa", null)))));
我很难理解这种转变。感觉很多信息都消失了。@SotiriosDelimanolis现在好多了?你想让杰克逊为格森做点什么吗?Gson扩展让你可以这样做。这很好,但它做了我想避免的事情,那就是我自己在字段上瞎混。我希望所有实体和它们的所有成员都这样,而不必枚举它们正如所写的,它不能做预期的事情,因为
serializedUsers
只得到测试和编写,而从不在其他地方使用。但是我有主意了,这是可以解决的它还使gson
实例依赖于上下文,并迫使我在每个请求/会话中使用它,而不是将其作为单个实例使用。但让我们称之为特性,它是概念的证明。关键部分是上下文依赖。集合是一个上下文,让您知道是否需要序列化父对象。问题是序列化程序是在顶层注册的,这使得上下文是全局的。另一个选项是创建允许本地上下文的jsonement
代理。
[{"id":3,"name":"Grampa"},{"id":2,"name":"Homer","fatherId":3},{"id":1,"name":"Bart","fatherId":2}]