Reputation: 61
I am getting a JSON
String as response as shown below
{"size":3,"page-size":3,"subscribers-aircraft":
[
{"company-name":"ATCOMPANYTEST","tailno":"N345","status":"ACTIVE","network-status":"ACTIVE","id":18501,"contact":"SS Theairtime","model":"A-380-800","note":null,"created-at":"Jun 29, 2015 7:42:54 AM","packages":2,"username":"ATAIRCRAFTTEST","external-account":null,"consumer-type":"AIRCRAFT","isp-id":18493,"parent-id":18497,"subscriber-feature-id":13,"status-code":null,"status-msg":null},
{"company-name":"The AIRTIME 3","tailno":"VT456","status":"ACTIVE","network-status":"ACTIVE","id":18489,"contact":"Ramesh Anantarapu","model":"C-21","note":null,"created-at":"Jun 25, 2015 8:27:16 AM","packages":0,"username":"ramesh23","external-account":null,"consumer-type":"AIRCRAFT","isp-id":18469,"parent-id":18473,"subscriber-feature-id":9,"status-code":null,"status-msg":null},
{"company-name":"The AIRTIME 3","tailno":"VT23","status":"ACTIVE","network-status":"OFFLINE","id":18485,"contact":"Ramesh Anantarapu","model":"747-100","note":null,"created-at":"Jun 23, 2015 2:49:15 PM","packages":1,"username":"ramesh","external-account":null,"consumer-type":"AIRCRAFT","isp-id":18469,"parent-id":18473,"subscriber-feature-id":5,"status-code":null,"status-msg":null}],
"status-code":"AIRTIME-P4000","status-msg":"Successfully"}
This is a flat response.
I am now struggling to map it to a top level POJO
called AircraftInfo
which contains two other POJOs
as its entities.
While for example : company-name, tailNo and status belongs directly to the AircraftInfo while user-name,id belongs to UserInfo POJO that is an entity in AircraftInfo.
Since the JSON response is flat, it is virtually turning out to be impossible to map such a response in a nested structure.
Can someone suggest the most elegant way to achieve?
Upvotes: 4
Views: 1178
Reputation: 34470
One option is to make use of the @JsonCreator
annotation:
public static class AircraftInfo {
private final String companyName;
private final String tailNo;
private final UserInfo userInfo;
@JsonCreator
public AircraftInfo(Map<String, Object> flatProperties) {
this.companyName = (String) flatProperties.get("company-name");
this.tailNo = (String) flatProperties.get("tailno");
UserInfo user = new UserInfo();
user.setUserName((String) flatProperties.get("username"));
user.setId((Integer) flatProperties.get("id"));
this.userInfo = user;
}
// getters for final fields
}
UserInfo
class would be as follows:
public class UserInfo {
private String userName;
private int id;
// getters and setters
}
You could deserialize your JSON to the following Response
POJO:
public class Response {
private int size;
@JsonProperty("page-size") // non standard JSON property name
private int pageSize;
@JsonProperty("subscribers-aircraft") // non standard JSON property name
private List<AircraftInfo> subscribersAircraft; // use class defined above!
@JsonProperty("status-code") // non standard JSON property name
private String statusCode;
@JsonProperty("status-msg") // non standard JSON property name
private String statusMsg;
// getters and setters
}
You could use these 2 classes as follows:
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setSerializationInclusion(Include.NON_NULL);
String json = // your exact json here, ESCAPED!
Response response = mapper.readValue(json, Response.class);
The response
instance should be structured as per your requirements now, despite your JSON's flat structure.
Upvotes: 2
Reputation: 14383
You could write a custom Deserializer. However, Jackson's Streaming API isn't the most easy tool to work with.
So my advice to you: load the JSON into a HashMap (simply call ObjectMapper.readValue()
with a Map.class
second arg) and then you can construct your Objects and populate their state from the map
Upvotes: 1