Cannot get @JsonIdentityInfo annotation to work

I have a bi-directional connection between two objects. I have a RESTful web service using Jersey 1.17 and Jackson 2.1.4. I also use the @JsonIdentityInfo annotation (apparently wrong) to stop Json from looping endlessly. However, the created Json is still an infinite loop between two objects.

First object:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") public class Child { private long value; private Parent parent; public long getValue() { return this.value; } public void setValue(long value) { this.value = value; } public Parent getParent() { return this.parent; } public void setParent(Parent parent) { this.parent = parent; } } 

The second object:

 @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") public class Parent { private long value; private Set<Child> childs = new HashSet<Child>(0); public long getValue() { return this.value; } public void setValue(long value) { this.value = value; } public Set<Child> getChilds() { return this.childs; } public void setChilds(Set<Child> childs) { this.childs = childs; } } 

And here is the method that Json generates.

 @GET @Path("/test") @Produces(MediaType.APPLICATION_JSON) public Child getChild() { Child child = new Child(); Parent parent = new Parent(); child.setValue(1L); parent.setValue(2L); child.setParent(parent); Set<Child> childs = new HashSet<Child>(0); childs.add(child); parent.setChilds(childs); return child; } 

EDIT:

As a result, Json looks like this:

 {"value":1,"parent":{"value":2,"childs":[{"value":1,"parent":{"value":2,"childs":[... 

And these 9 lines were repeated in the server log file again and again ...

 at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86) at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:72) at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23) 

And the web.xml file looks like this:

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Jersey REST Service</display-name> <servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>test</param-value> </init-param> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping> </web-app> 
+2
source share
2 answers

You say you are using Jackson 2.1.4, but stacktrace shows Jackson with packages starting with " org.codehaus.jackson ", which is the base package for Jackson 1.x. The base package for Jackson 2.x is " com.fasterxml.jackson ". Therefore, Jersey is configured with Jackson 1.x (most likely 1.9.2, and by default on Jersey 1.17 ). I assume that you are commenting on your code using annotations imported from Jackson 2.x, but the Jackson library used by Jersey is not aware of this and therefore cannot be serialized.

Your code works well for me with Jackson 2.3.0.

+5
source

For two-way communication between fields, you should take a look at the @JsonManagedReference and @JsonBackReference annotations. I do not think that this behavior can be achieved using @JsonIdentifyInfo at all.

 public class Parent { private long value; @JsonManagedReference private Set<Child> childs = new HashSet<Child>(0); public long getValue() { return this.value; } public void setValue(long value) { this.value = value; } public Set<Child> getChilds() { return this.childs; } public void setChilds(Set<Child> childs) { this.childs = childs; } } 

...

 public class Child { private long value; @JsonBackReference private Parent parent; public long getValue() { return this.value; } public void setValue(long value) { this.value = value; } public Parent getParent() { return this.parent; } public void setParent(Parent parent) { this.parent = parent; } } 

Below you can find examples here .

+3
source

Source: https://habr.com/ru/post/1336748/


All Articles