{
"Filters": [{
"Decription": "Default",
"FieldSelected": {
"AppointmentDate": true,
"AppointmentDateOrder": 1
"ptStatusOrder": 3
},
"FilterID": 1
}, {
"Decription": "chart",
"FieldSelected": {
"AppointmentDate": true,
"AppointmentDateOrder": 1,
"ptStatusOrder": 0
},
"FilterID": 2
}]
}
I am getting a response of this structure, how do i map it to my POJO class. Can anyone give a sample POJO class for this json structure. I am using Gson for Request and Response.
Just map one Json Object as a Java Class. And make an Array of Object as a List..
Like, (pseudo code only)
You are using GSON library so import SerializedName in your pojo classes.
import com.google.gson.annotations.SerializedName;
Pojo Class looks like,
public class Filter {
#SerializedName("Decription") // This requires same as your Json key
public String description;
#SerializedName("FieldSelected") // The Json Object of FieldSelected
public Field listDetails;
}
public class Field {
#SerializedName("ptStatusOrder")
public int status;
#SerializedName("AppointmentDateOrder")
public int dateOrder;
#SerializedName("AppointmentDate")
public boolean appDate;
}
And main ListFileter class,
public class ListFilter {
#SerializedName("Filters")
public List<Filter> listFilter;
}
And in Android code,
Gson gson = new Gson();
ListFilter listFilter = gson.fromJson(jsonResponse, ListFilter.class);
Related
The single json sample object looks like this:
"Events":[{
"sport_event_id": "sr:sport_event:27636100",
"start_date": "2021-06-22T18:00:00+00:00",
"sport_name": "Soccer",
"competition_name": "UEFA Champions League",
"competition_id": "sr:competition:7",
"season_name": "UEFA Champions League 21/22",
"competitors": [
{
"id": "sr:competitor:37863",
"name": "SS Folgore Falciano Calcio",
"country": "San Marino",
"country_code": "SMR",
"abbreviation": "FFC",
"qualifier": "home",
"gender": "male"
},
{
"id": "sr:competitor:277829",
"name": "FC Prishtina",
"country": "Kosovo",
"country_code": "KOS",
"abbreviation": "PRI",
"qualifier": "away",
"gender": "male"
}
],
"venue": {
"id": "sr:venue:8329",
"name": "Elbasan Arena",
"capacity": 12500,
"city_name": "Elbasan",
"country_name": "Albania",
"map_coordinates": "41.115875,20.091992",
"country_code": "ALB"
},
"probability_home_team_winner": 2.5,
"probability_draw": 88.1,
"probability_away_team_winner": 9.4
},
Please help me understand how to do it. I assume I need to use the Gson library and HashMaps.
I watched a couple of videos on Youtube on how to do a map for a json object. But all I could find is for simple objects with two strings. I can't get around on how to do it for a more complex json file like this. Would be very thankful if somebody posted a code example for this file.
There are a few libraries available in java that can be used to convert json to a Map.
The first popular library is Gson, which can be used to parse json and convert it to a Map with the following code:
import com.google.gson.Gson;
import java.util.Map;
public static void convert(){
String json = "{\"key1\":\"value1\",\"key2\":\"value2\"}";
Gson gson = new Gson();
Map<String, String> map = gson.fromJson(json, Map.class);
...
}
You can read more about that approach here.
Another popular library is Jackson:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public static void convert(){
String json = "{\"key1\":\"value1\",\"key2\":\"value2\"}";
ObjectMapper objectMapper = new ObjectMapper();
Map<String, String> map = objectMapper.readValue(json, Map.class);
...
}
You can read more about that approach right here
I would use a site like this to generate Java classes from your sample JSON (see below). Then use Jackson objectMapper to deserialise as follows:
Root root = objectMapper.readValue(myJsonString, Root.class); */
Then you can do stuff like this to get the name of first competitor in the first event (SS Folgore Falciano Calcio):
root.get(0).competitors.get(0).name
Generated class structure. You probably should make the fields private and add getters.
public class Root{
#JsonProperty("Events")
public ArrayList<Event> events;
}
public class Competitor{
public String id;
public String name;
public String country;
public String country_code;
public String abbreviation;
public String qualifier;
public String gender;
}
public class Event{
public String sport_event_id;
public Date start_date;
public String sport_name;
public String competition_name;
public String competition_id;
public String season_name;
public ArrayList<Competitor> competitors;
public Venue venue;
public double probability_home_team_winner;
public double probability_draw;
public double probability_away_team_winner;
}
public class Venue{
public String id;
public String name;
public int capacity;
public String city_name;
public String country_name;
public String map_coordinates;
public String country_code;
}
I'm using Moshi as converter for Retrofit, but for one particular request it doesn't work and exception is thrown:
com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $.results
The JSON I want to parse:
{
"id": 423,
"results": [
{
"id": "53484dfec3a3684b930000bd",
"iso_639_1": "en",
"iso_3166_1": "US",
"key": "u_jE7-6Uv7E",
"name": "Trailer",
"site": "YouTube",
"size": 360,
"type": "Trailer"
},
{
"id": "57e16bb0c3a36808bc000641",
"iso_639_1": "en",
"iso_3166_1": "US",
"key": "BFwGqLa_oAo",
"name": "Trailer",
"site": "YouTube",
"size": 1080,
"type": "Trailer"
}
]
}
The model classes:
public class VideosResponse {
private int id;
private List<Video> results;
//+ getters & setters
}
public class Video {
private String id;
#Json(name = "iso_639_1")
private String iso6391;
#Json(name = "iso_3166_1")
private String iso31661;
private String key;
private String name;
private String site;
private Integer size;
private String type;
//+getters & setters
}
This is Retrofit call:
#GET("3/movie/{id}/videos")
Call<List<Video>> movieVideos(
#Path("id") int id,
#Query("api_key") String apiKey);
So as you can see I'm expecting list of objects, but the JSON is actually an objecy itself, therefore I prepared my custom converter:
public class VideosJsonConverter {
#FromJson
public List<Video> fromJson(VideosResponse json) {
return json.getResults();
}
}
... and I'm adding it to my Retrofit like that:
public Retrofit provideRetrofit(#Named("baseUrl") String basUrl) {
Moshi moshi = new Moshi.Builder().add(new VideosJsonConverter()).build();
return new Retrofit.Builder()
.baseUrl(basUrl)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build();
}
My custom converter isn't actually called so it looks like Moshi can't convert JSON to my VideosResponse wrapper class. If I change my converter to accept Map<String, Object> it goes there, but not for VideosResponse. It also works when I change my retrofit enpoint to return directly VideosResponse. Is it possible that there is a conflict with other POJO classes (I have similar classes but with a list of different objects)?
The problem is that the adapter is going to be used by both your desired result and the inner list in VideosResponse. So, the adapter is expecting a VideoResponse-formatted JSON blob within the VideoResponse and fails when it finds the real array on reentry.
You can qualify one of the lists to differentiate them.
Here's an example of qualifying the resulting list.
#Retention(RUNTIME)
#JsonQualifier
public #interface Wrapped {
}
public class VideosJsonConverter {
#Wrapped #FromJson
public List<Video> fromJson(VideosResponse json) {
return json.results;
}
#ToJson
public VideosResponse toJson(#Wrapped List<Video> value) {
throw new UnsupportedOperationException();
}
}
#GET("3/movie/{id}/videos")
#Wrapped
Call<List<Video>> movieVideos(
#Path("id") int id,
#Query("api_key") String apiKey);
I have to parse a REST response in json and it has a lot of nested lists with many objects.
The response contains an item called "ObjectList" which has a list and inside, two elements, "ObjectA" and "ObjectB". I don't know how to parse the response to objects using Jackson annotations.
The json looks like this:
"ObjectList": [
{
"ObjectA": {
"property1": false,
"property2": true
},
"ObjectB": {
"property1": 66,
"property2": true
},
{
"ObjectA": {
"property1": false,
"property2": true
},
"ObjectB": {
"property1": 66,
"property2": true
}
}
]
}
My code looks like this
ResponseEntity<Response> response = restTemplate.exchange(URL, HttpMethod.GET, request, Response.class);
Response response = response.getBody();
Response is:
#JsonIgnoreProperties(ignoreUnknown = true)
public class TimesheetListResponse {
#JsonProperty("ObjectA")
private List<ObjectA> objectAList;
#JsonProperty("ObjectB")
private List<ObjectB> objectBList;
That does not work at all, and I'm confused about how to map this.
According to your requirement the model structure may look like below. Within the objectList map in Response object, you need to add HashMap with keys as "ObjectA"/"ObjectB" string and value as instance of ObjectA/ObjectB. I have taken value type of Map as Object, so that any object type A/B can fit in there. Add corresponding #JsonXXX annotations.
public class Response {
private List<Map<String,Object>> objectList;
//Getters & Setters
}
public class ObjectB {
String propB1;
String propB2;
}
public class ObjectA {
String propA;
String propA1;
}
I also would consider the entry in the list as another wrapper object that can either ObjectA or ObjectB. I.e.
#JsonIgnoreProperties(ignoreUnknown = true)
public final class Parent {
#JsonProperty("ObjectList")
private List<ChildWrapper> objectList = new ArrayList<>();
}
#JsonIgnoreProperties(ignoreUnknown = true)
public final class ChildWrapper {
#JsonProperty("ObjectA")
private Child ObjectA;
#JsonProperty("ObjectB")
private Child ObjectB;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public final class Child {
#JsonProperty("property1")
private int property1;
#JsonProperty("property2")
private boolean property2;
}
It seems that the mapping was fine, I only had to initialize the Arraylist. The main issue was that the endpoint was returning empty because of a parameter that I forgot.
I am consuming a REST web services using REST template in my project which returns a JSON as below:
{"data": [{
"id": "INT-1468819244684-event-no-97",
"object1": {
"JSONString": "{\"object2\":[{\"object3\":\"value3\",\"object4\":\"value4\"}]}"
}
}]
}
While consuming the above JSON response I am able to create a bean class and able to dump JSON object/values into the same.
But the problem is above json response contains a string as below:
"JSONString": "{\"object2\":[{\"object3\":\"value3\",\"object4\":\"value4\"}]}"
which is actually a json. So I have a bean in which I can fetch JSONString as String. So currently I can use below bean structure to fetch response in objects:
public class response {
Data data;
}
public class Data {
String id;
Object1 object1;
}
public class Object1 {
String jsonString;
}
But above jsonString contains a string in the form of json, so I want to somehow convert this JSON String to JSON Object at run time only when other objects are created and dump all its content in the same bean so that application should be ready to use its content. So ideally my bean hierarchy should be something like below:
public class response {
Data data;
}
public class Data {
String id;
Object1 object1;
}
public class Object1 {
JSONString jsonString;
}
public class JSONString {
Object2 object2;
}
public class Object2 {
String object3;
String object4;
}
Please guide me how to do the same.
You can use Jackson's ObjectMapper.readValue in this way:
// Create or use your existing ObjectMapper
ObjectMapper om = new ObjectMapper();
#JsonProperty("JSONString")
public String getJSONString() {
if (this.jsonString == null)
return null;
return om.writeValueAsString(this.jsonString);
}
public void setJSONString(String s) {
this.jsonString = om.readValue(s, JSONString.class);
}
I have json that looks like this:
{
"summary":{
"somefield1":"somevalue1",
"Twilio":{
"field1":"value1",
"field2":"value2"
},
"Tropo":{
"field1":"value1",
"field2":"value2"
},
...
}
}
I would like to deserialize it into a java class that looks like this:
public class Summary {
private String someField1;
private List<Vendor> vendors;
}
public class Vendor {
private String name;
private String field1;
private String field2;
}
So the Twilio and Tropo need to become Vendor objects in a list where Vendor.name == "Twilio" or "Tropo".
I'm sure jackson has the tools I need to work with this structure but I've been striking out with web searches.
You can do it with combination of #JsonRootName and #JsonAnySetter annotations. Your Summary class should look like this:
#JsonRootName("summary")
class Summary {
#JsonProperty("somefield1")
private String someField1;
private List<Vendor> vendors = new ArrayList<Vendor>();
#JsonAnySetter
public void setDynamicProperty(String vendorName, Map<String, String> properties) {
Vendor vendor = new Vendor();
vendor.setName(vendorName);
vendor.setField1(properties.get("field1"));
vendor.setField2(properties.get("field2"));
vendors.add(vendor);
}
//getters,setters,toString methods
}
Example usage:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
System.out.println(mapper.readValue(json, Summary.class));
Above source code shows below string for your JSON:
Summary [someField1=somevalue1, vendors=[Vendor [name=Twilio, field1=value1, field2=value2], Vendor [name=Tropo, field1=value1, field2=value2]]]
If you want to use your objects:
public class Summary {
private String someField1;
private List<Vendor> vendors;
}
public class Vendor {
private String name;
private String field1;
private String field2;
}
you have to modify your json. Actually a structure like the one you defined will be converted to something like:
{
"summary": {
"somefield1": "somevalue1",
"vendors": [
{
"name": "Twilio",
"field1": "value1",
"field2": "value2"
},
{
"name": "Tropo",
"field1": "value1",
"field2": "value2"
}
]
}
}
a list is defined between the square brackets [], and in your case it's a list of objects {}.
I would change your json if you can, because the structure you post will be a mess to work with. The one I pointed out, that matches your java objects, is more clear.
The JSON structure you've got would match this java structure where the key of vendors is the vendor name.
public class Summary {
private String someField1;
private Map<String,Vendor> vendors;
}
public class Vendor {
private String field1;
private String field2;
}
The classes you've specified would support this JSON:
{
"somefield1":"somevalue1",
"vendors":[{
"name":"Twilio"
"field1":"value1",
"field2":"value2"
},
{
"name":"Tropo"
"field1":"value1",
"field2":"value2"
},
...]
}
I don't think you can achieve what you want with jackson as the name is outside the "Vendor" object.