Reputation: 705
I have following json having an array with field name page_names which can contain either string or another object. Is there any way to convert it into java object using jackson?? I have two classes: PageStructure corresponding to whole object and PageInfo for storing object like { "name": "Candidate Information", "section":2 }.
{
"url": "http://example.com",
"is_auth_required": false,
"page_names": [
"Hello",
{
"name": "Candidate Information",
"section":2
},
{
"page_name": "Resume and Cover Letter",
"section":3
}
]
}
I can convert using following code but then I have to recognize whether object has string or PageInfo explicitly.
@JsonIgnoreProperties(ignoreUnknown = true)
public class PageStructure {
@JsonProperty("url")
String Url;
@JsonProperty("is_auth_required")
boolean isAuthRequired = true;
@JsonProperty("page_names")
List<Object> PageNames;
//GETTERS AND SETTERS
}
Is there any other approach where It is possible to give page_names is either String or PageInfo object??
Upvotes: 1
Views: 1214
Reputation: 8691
There is a setter that lets you take in any field and its name, and do with it what you want.
@JsonAnySetter
public void set(String name, Object value) {
if (name == "page_names")
if (value instanceof String)
// Treat it as a string
else
// Treat it as a JSON object
}
This is the simplest solution, but it ties your model to the deserialization. Alternatively, you could define your own deserializer:
public class PageStructureDeserializer extends JsonDeserializer<PageStructure> {
@Override
public PageStructuredeserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
// Look through the node, check whether the pages are strings or objects
// See more info at http://www.baeldung.com/jackson-deserialization
return new PageStructure(...);
}
}
Then just add your deserializer to an object mapper, and away you go.
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(PageStructure.class, new PageStructureDeserializer());
mapper.registerModule(module);
PageStructure readValue = mapper.readValue(json, PageStructure.class);
This is definitely a lot more complicated and lengthy way of doing it, but it means your plain-old-data object does not depend on the JSON library. You can change the library, or even change from JSON to XML, without having to change the data model. If this is part of a large shared codebase, then it might be worth the effort to make the abstraction.
Upvotes: 1