Reputation: 4175
Given POJO:
@XmlRootElement
public class Categories implements Serializable {
private int id;
private String name;
private Categories parent;
// ....
}
I'd like to serialize it to following json:
{ id: 1, name: "some name", parent: 5 }
So, main challenge here is to represent parent object as its id. Same thing i want for deserialization.
I scannned rather large Jackson wiki and did not found anything that allowed to accomplish this without writing plethora of custom code. I think this is pretty common task and solution shold be somewhere nearby.
Also it would be nice if solution will allow to customize null value cases.
UPD:
Now trying to use XmlTypeAdapter
approch, not happy with it btw, because i need to write TypeAdapter
for everyy single type i have and all they going to contain almost the same code:
public class CategoriesTypeAdapter extends XmlAdapter<Integer, Categories> {
@Inject
CategoriesFacade dao;
@Override
public Categories unmarshal(Integer v) throws Exception {
return dao.find(v);
}
@Override
public Integer marshal(Categories v) throws Exception {
return v.getId();
}
}
Change in Categories.java:
@XmlJavaTypeAdapter(CategoriesTypeAdapter.class)
private Categories parent;
UPD1:
And this is also not worked for me, at least deserializing now always return null in place of object, no idea how to debug this : For this JSON:
{ id: 1, name: "test", parent: 5 }
I get parent always null now:
Categories{categoryId=1, name="test", parentId=null}
UPD2:
I found that htere is my fail in tis isssue, just did not setup things propertly, and my web.xml was lacking this entry:
<servlet>
<servlet-name>Jersey Web Application</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>com.neopod.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
Upvotes: 1
Views: 2222
Reputation: 29663
Use propery access to field Categories
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Categories implements Serializable {
@XmlElement
Integer categoryId;
@XmlElement
String name;
Categories parentId;
public Integer getCategoryId() {
return categoryId;
}
public String getName() {
return name;
}
@XmlElement
public Integer getParentId()
{
return parentId == null ? null : parentId.getCategoryId();
}
}
test
Categories c = new Categories();
c.categoryId = 1;
c.name = "name";
Categories c1 = new Categories();
c1.categoryId = 2;
c.parentId = c1;
System.out.println(new ObjectMapper().writeValueAsString(c));
output
{"categoryId":1,"parentId":2,"name":"name"}
EDIT:
make two gatters.
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Categories implements Serializable {
@XmlElement
Integer categoryId;
@XmlElement
String name;
Categories parentId;
public Integer getCategoryId() {
return categoryId;
}
public String getName() {
return name;
}
public Category getParentId()
{
return parentId;
}
@XmlElement(name = "parentId")
Integer getParentIdForJSON()
{
return parentId == null ? null : parentId.getCategoryId();
}
}
Upvotes: 1
Reputation: 116472
There are two ways that might work, depending on exact semantics.
First is to use annotation pair @JsonManagedReference
/ @JsonBackReference
, where first is used on "forward" property, and second on "backward" reference. In those cases, second property is not included in serialization, but is recovered during deserialization. This works for simple hierarchic objects.
Second is @JsonIdentityInfo
(added in 2.0), and it adds support for arbitrary object references, regardless of direction. It works by serialization each Object as-is the first time it is seen; but on later references serializing them as ids. Deserialization restores linkage automatically.
Upvotes: 4