[英]Java object serialization and conversion to JSON
I have a Java object. 我有一个Java对象。 It has numerous fields that have references to other different kinds of Java objects and sometimes, to itself.
它具有众多字段,这些字段引用了其他不同种类的Java对象,有时还引用了其自身。 This object can be best described as a map (or graph) with bi-directional references (or cycles).
最好将此对象描述为具有双向参考(或循环)的地图(或图形)。 I am not authorized to analyze its structure, but in order to solve a problem, I have to serialize this graph and store it in a JSON String.
我无权分析其结构,但为了解决问题,我必须对该图进行序列化并将其存储在JSON字符串中。
The fact that I can't really have a look at the structure of the object, using library classes is my only option (as far as I think). 我实际上不能真正使用对象类来查看对象的结构,这是我唯一的选择(就我而言)。 I have tried json-io, json-lib, google genson, gson and flexjson.
我尝试了json-io,json-lib,google genson,gson和flexjson。 But all of these libraries either get stuck and throw an exception due to the presence of a cycle or are able to return a json (only json-io does this) but with a lot of important fields skipped(the ones that are lazy-loaded, and need getters).
但是所有这些库要么由于存在循环而陷入困境并抛出异常,要么能够返回json(只有json-io会这样做),但是跳过了许多重要的字段(被延迟加载的字段) ,并且需要吸气剂)。
Question: Is there something that exists that I might be missing while testing the above listed libraries just to address my problem? 问题:在测试上面列出的库时,是否仅存在某种我想解决的问题?
The Java object I have is really convoluted but I don't expect it to be as convoluted as objects that might be used by big websites like facebook. 我拥有的Java对象确实很复杂,但是我不希望它像Facebook之类的大型网站所使用的对象那样复杂。 What are some key libraries and their specific configuration that can be used to address my problem?
有哪些密钥库及其特定配置可用于解决我的问题?
I think the best option for you is Jackson Streaming API . 我认为最适合您的选择是Jackson Streaming API 。 It allows you to serailaze a POJO into json while teraversing the Object graph, thus maintaining control over the serailization process and you can detect and handle circular references and any other special cases.
它允许您在对对象图进行划分时将POJO序列化为json,从而保持对序列化过程的控制,并且可以检测和处理循环引用以及任何其他特殊情况。
EDIT: I tried to implement an example that handles circular references but i could not complete it. 编辑:我试图实现一个示例处理循环引用,但我无法完成它。 Here are my intermediate findings:
这是我的中间发现:
ObjectMapper.WriteValue(...)
results in the following Exception com.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle
which means Jackson can detect cases of self referencing. ObjectMapper.WriteValue(...)
导致以下异常com.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle
,这意味着Jackson可以检测到自引用的情况。 The default derializer does not know how to handle this case. mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);
mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);
来关闭抛出异常的默认行为mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);
when this is set, The default derializer will cause stack overflow. An example class that can have self reference: 可以具有自我引用的示例类:
public class Node {
public String name = "";
public Node child = null;
public Node(String name) { this.name = name; }
public String getname() { return name; }
public Node getChild() { return child; }
public void setChild(Node n) { child = n; }
}
the custom serializer 自定义序列化器
public class NodeJsonSerializer extends JsonSerializer<Node> {
// list so we can detect multiple cases of self references
static List<Node> alreadySerializedNodes = new ArrayList<>();
@Override
public void serialize(Node n, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException {
for (Node alreadySerialized : alreadySerializedNodes) {
// do not invoke equals() since you want to find duplicate references
if (alreadySerialized == n) {
// mark this as self reference
gen.writeStartObject();
gen.writeStringField("node-ref", alreadySerialized.getname());
gen.writeEndObject();
return;
}
}
alreadySerializedNodes.add(n);
// default derialization ...
gen.writeStartObject();
gen.writeStringField("name", n.getname());
gen.writeObjectField("child", n.getChild());
gen.writeEndObject();
}
}
Calling: 致电:
Node n1 = new Node("n1");
n1.setChild(n1); // self referencing
ObjectMapper mapper = new ObjectMapper();
// registering custom serializer is through module
SimpleModule sm = new SimpleModule("MyModule");
sm.addSerializer(Node.class, new NodeJsonSerializer());
// making sure default serializer ignores self referencing is through module mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);
mapper.registerModule(sm);
System.out.println(mapper.writeValueAsString(n1));
output is {"name":"n1","child":{"node-ref":"n1"}}
输出为
{"name":"n1","child":{"node-ref":"n1"}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.