Reputation: 776
I am working with Jackson parsing and wondering if there is any way in Jackson to create such JSON document?
"fields": {
"A" : { "ref" : 1},
"B" : { "ref" : 2},
"C" : { "ref" : 1}
},
"refs" : [
{"@id" : 1, "values" : ["X", "Y", "Z"] },
{"@id" : 2, "values" : ["1", "2", "3] }
]
Where "A" will have the reference to array of strings defined in "refs" element
Upvotes: 0
Views: 137
Reputation: 14328
It can be done with the help of Jackson's Object Identity feature:
the values collections need to be wrapped in their own class that is annotated so that Jackson generates object id for distinct collections:
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Values
{
public List<String> values = new ArrayList<>();
public Values() {}
public Values(String... values) {
this.values = Arrays.asList(values);
}
/**
* implement equals() and hashCode() so that instances can be put into Maps Sets and such
*/
@Override
public boolean equals(Object other) {
return other instanceof Values ? ((Values)other).values.equals(values) : false ;
}
@Override
public int hashCode() {
return values.hashCode();
}
}
the following class wraps ref
and fields
. serialization order is exlicitly defined so that jackson will generate object ids for the contents of refs
@JsonPropertyOrder({"refs", "fields"})
public class MyClass
{
public Set<Values> refs = new HashSet<>();
public Map<String, Values> fields = new HashMap<>();
public MyClass()
{
Values v1 = new Values("X", "Y", "Z");
Values v2 = new Values("1", "2", "3");
fields.put("A", v1);
fields.put("B", v2);
fields.put("C", v1);
fields.values().forEach(value -> refs.add(value));
}
}
serialization of MyClass
new ObjectMapper().writeValue(System.out, new MyClass());
produces
{"refs":[{"@id":1,"values":["1","2","3"]},{"@id":2,"values":["X","Y","Z"]}],"fields":{"A":2,"B":1,"C":2}}
Upvotes: 1