retrofit call on object that contains another object represented by an array - java

I have json data :
[
{
"RouteNo": "004",
"RouteName": "POWELL/DOWNTOWN/UBC",
"Direction": "WEST",
"Schedules": [
{
"Destination": "UBC",
"ExpectedCountdown": -4,
},
{
"Destination": "Downtown",
"ExpectedCountdown": -6,
}
]
},
{
"RouteNo": "006",
"RouteName": "Grange str",
"Direction": "South",
"Schedules": [
{
"Destination": "Victoria",
"ExpectedCountdown": -9,
},
{
"Destination": "College station",
"ExpectedCountdown": -15,
}
]
}
]
And I have my model Route.java:
public class Route {
public String getRouteNo() {
return RouteNo;
}
public void setRouteNo(String routeNo) {
RouteNo = routeNo;
}
public String getRouteName() {
return RouteName;
}
public void setRouteName(String routeName) {
RouteName = routeName;
}
public Route(String routeNo, String routeName) {
RouteNo = routeNo;
RouteName = routeName;
}
private String RouteNo;
private String RouteName;
}
My question is how should I insert Schedules object you can see in json data into Route model? I am confused in terms of (as far as I understood) it is an object containing an array and I am not sure how to represent it in this case. And how actually get the data from it in retrofit call? I need to get each destination for each route.

Update Route to be:
public class Route {
public String getRouteNo() {
return RouteNo;
}
public void setRouteNo(String routeNo) {
RouteNo = routeNo;
}
public String getRouteName() {
return RouteName;
}
public void setRouteName(String routeName) {
RouteName = routeName;
}
public Route(String routeNo, String routeName) {
RouteNo = routeNo;
RouteName = routeName;
}
private String RouteNo;
private String RouteName;
private List<Schedule> schedules; // add mutators with #JsonProperty annotation
}
Then create the Schedule class as described by the above JSON

Related

Find values from list with key value pair

I want to find the key value pair from a list. I want to put the values into a parameter from another method. I have a deserialzied map that contains the list called "InfoFields" here is my json string:
{
"operation": "get-id",
"payload": {
"ApplicationContext": {
"Context": "JORDFEIL",
"SenderId": "xxx",
"subContext": ""
},
"supportIssue": {
"InfoFields": [
{
"Key": "key1",
"Value": "value1"
},
{
"Key": "key2",
"Value": "value2"
},
{
"Key": "key3",
"Value": "value3"
}
],
}
},
"type": "~:CustomerInquiry",
}
Here is my wrapper class aswell
public class WebskjemaModel {
public class ApplicationContext {
public String Context;
public String SenderId;
public String subContext;
}
public String operation;
public Payload payload;
public String type;
public class InfoFields {
public String Key;
public String Value;
}
public class Payload {
public ApplicationContext ApplicationContext;
public SupportIssue supportIssue;
}
public class SupportIssue {
public List<InfoFields> InfoFields;
public String assignId;
public String businessObjectType;
public String comment;
public String contactDate;
public String contactName;
public String customerName;
public String customerNo;
public String docClass;
public String format;
public String objectDescription;
public String objectId;
public String subject;
}
public static WebskjemaModel parse(String json) {
return (WebskjemaModel) System.JSON.deserialize(json, WebskjemaModel.class);
}
}
I have created a map that contains the deserialzed object, now i want to map the fields for a single case. Here is what i have tried, but i cant seem to get the values from the key and from the value:
public with sharing class WebskjemaCaseCreator {
#TestVisible
private Map<Id, Case> cases { get; set; }
#TestVisible
private Map<Id, WebskjemaModel> webskjemaModels = new Map<Id, WebskjemaModel>();
public WebskjemaCaseCreator(Map<Id, Case> cases) {
this.cases = cases;
deserializeJson();
mapFields();
}
private void deserializeJson() {
for (Id caseId : cases.keySet()) {
Case c = cases.get(caseId);
WebskjemaModel model = WebskjemaModel.parse(c.Webskjemablob__c);
webskjemaModels.put(caseId, model);
}
}
private void mapFields() {
for (Id caseId : cases.keySet()) {
Case c = cases.get(caseId);
WebskjemaModel model = webskjemaModels.get(caseId);
}
}
private void mapFieldsForSingleCase(Case c, WebskjemaModel model) {
String context = model.payload.ApplicationContext.Context;
List<WebskjemaModel.InfoFields> myinfoFields = model.payload.supportIssue.InfoFields;
for (WebskjemaModel.InfoFields fields : myinfoFields) {
mapInfoField(c, context, fields.get(key), fields.get(value));
}
// TODO: Find WebskjemaModel inforfields and loop
// for (list of infofields for this model only){
// TODO: call method mapInfoField
// }
}
private void mapInfoField(Case c, String context, String infoFieldKey, String infoFieldValue) {
WebskjemaMapping__mdt[] webskjemarecords = [
SELECT CaseField__c, Context__c, JsonField__c, IfsField__c
FROM WebskjemaMapping__mdt
];
// TODO: Find Case field from custom meta data type mapping, based on context and infoFielfKey
// TODO: Put value from inforFieldValue into Case field
}
}

Wrapping ResponseEntity into another object

I have the following response structure.
{
"URL": "",
"sites": [
{
"details": "",
"details2": "",
"details3": [
{
"moreDetails": "",
"moreDetails2": "",
}
]
},
{
"details": "",
"details2": "",
"details3": [
{
"moreDetails": "",
"moreDetails2": "",
}
]
}
]
}
This is accomplished by having multiple models.
SitesResponse
Sites
Details
MoreDetails
All of them have getter and setters and I just set up the response in the controller. Is there a way to move ALL of the response to a parent object without rewriting the hierarchy?
For an example, something like this:
{
"results": {
"URL": "",
"sites": [
{
"details": "",
"details2": "",
"details3": [
{
"moreDetails": "",
"moreDetails2": ""
}
]
},
{
"details": "",
"details2": "",
"details3": [
{
"moreDetails": "",
"moreDetails2": ""
}
]
}
]
}
}
you have to put them inside another object as below :
Result Model :
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"URL",
"sites"
})
public class Results {
#JsonProperty("URL")
private String uRL;
#JsonProperty("sites")
private List < Site > sites = null;
#JsonProperty("URL")
public String getURL() {
return uRL;
}
#JsonProperty("URL")
public void setURL(String uRL) {
this.uRL = uRL;
}
#JsonProperty("sites")
public List < Site > getSites() {
return sites;
}
#JsonProperty("sites")
public void setSites(List < Site > sites) {
this.sites = sites;
}
}
Site Model:
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"details",
"details2",
"details3"
})
public class Site {
#JsonProperty("details")
private String details;
#JsonProperty("details2")
private String details2;
#JsonProperty("details3")
private List < Details3 > details3 = null;
#JsonProperty("details")
public String getDetails() {
return details;
}
#JsonProperty("details")
public void setDetails(String details) {
this.details = details;
}
#JsonProperty("details2")
public String getDetails2() {
return details2;
}
#JsonProperty("details2")
public void setDetails2(String details2) {
this.details2 = details2;
}
#JsonProperty("details3")
public List < Details3 > getDetails3() {
return details3;
}
#JsonProperty("details3")
public void setDetails3(List < Details3 > details3) {
this.details3 = details3;
}
Details Model :
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"moreDetails",
"moreDetails2"
})
public class Details3 {
#JsonProperty("moreDetails")
private String moreDetails;
#JsonProperty("moreDetails2")
private String moreDetails2;
#JsonProperty("moreDetails")
public String getMoreDetails() {
return moreDetails;
}
#JsonProperty("moreDetails")
public void setMoreDetails(String moreDetails) {
this.moreDetails = moreDetails;
}
#JsonProperty("moreDetails2")
public String getMoreDetails2() {
return moreDetails2;
}
#JsonProperty("moreDetails2")
public void setMoreDetails2(String moreDetails2) {
this.moreDetails2 = moreDetails2;
}
}
Holder Model:
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"results"
})
public class Holder {
#JsonProperty("results")
private Results results;
#JsonProperty("results")
public Results getResults() {
return results;
}
#JsonProperty("results")
public void setResults(Results results) {
this.results = results;
}
}
then you can pass the Holder Model as a response

Spring Convert enity manager getResultList results to JSON

I'm quite new to spring and I'm using spring entitymanager.createquery to make query and get the result from database.
So when make a http get this method executes to get all the patient name
public List<PatientModel> fetchallpatients (){
Query q = entityManager.createNativeQuery("select * from patient p ");
List <PatientModel> patientList=q.getResultList();
System.out.println(patientList);
return patientList;
}
it is returning
[[
1,
"patientname",
"patientphone",
"patientgender",
"patientinsurance",
"patientage",
"patientdiagnosis",
"patientaddreq",
"patientemr"
],
[
2,
"test",
"patientphone",
"patientgender",
"patientinsurance",
"patientage",
"patientdiagnosis",
"patientaddreq",
"patientemr"
],
[
3,
"react",
"12312",
"male",
"react",
"56",
"dsa",
"ads",
"das"
],
[
4,
"sign",
"asd",
"male",
"react",
"56",
"Diagnose 2",
"Ventilator",
"on"
],
[
5,
"good",
"3213",
"male",
"react",
"56",
"Diagnose 3",
"ICU",
"on"
] ]
Front end I'm using react and I need this data to be in JSON format.
I have a POJO class for corresponding table:
package io.login.model;
import java.io.Serializable;
public class PatientModel {
String patientname;
String patientage;
String patientgender;
String patientinsurance;
String patientphone;
String patientaddreq;
String patientemr;
public String getPatientname() {
return patientname;
}
public void setPatientname(String patientname) {
this.patientname = patientname;
}
public String getPatientage() {
return patientage;
}
public void setPatientage(String patientage) {
this.patientage = patientage;
}
public String getPatientgender() {
return patientgender;
}
public void setPatientgender(String patientgender) {
this.patientgender = patientgender;
}
public String getPatientinsurance() {
return patientinsurance;
}
public void setPatientinsurance(String patientinsurance) {
this.patientinsurance = patientinsurance;
}
public String getPatientphone() {
return patientphone;
}
public void setPatientphone(String patientphone) {
this.patientphone = patientphone;
}
public String getPatientdiagnosis() {
return patientdiagnosis;
}
public void setPatientdiagnosis(String patientdiagnosis) {
this.patientdiagnosis = patientdiagnosis;
}
public String getPatientaddreq() {
return patientaddreq;
}
public void setPatientaddreq(String patientaddreq) {
this.patientaddreq = patientaddreq;
}
public String getPatientemr() {
return patientemr;
}
public void setPatientemr(String patientemr) {
this.patientemr = patientemr;
}
String patientdiagnosis;
public PatientModel(String patientname, String patientage, String patientgender, String patientinsurance, String patientphone, String patientdiagnosis, String patientaddreq, String patientemr) {
this.patientname = patientname;
this.patientage = patientage;
this.patientgender = patientgender;
this.patientinsurance = patientinsurance;
this.patientphone = patientphone;
this.patientdiagnosis = patientdiagnosis;
this.patientaddreq = patientaddreq;
this.patientemr = patientemr;
}
}
But I need the result like
{ { "patientname":"xyz"
"patientphone":"xyz"
"patientinsurance":"xyz"
"patientgender":"xyz"
"patientdiagnosis":"xyz"
"patientaddreq":"xyz" ... so on
}
}
you are returning List<String[]> and expect it to be a JSON list of your POJO?
change your method to return what is expected, like:
#Transactional
public List<PatientModel> fetchallpatients () {
Query q = entityManager.createNativeQuery("select * from patient p ");
List <PatientModel> patientList = q.getResultList();
System.out.println(patientList);
return patientList;
}

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 5921 path $.data[5].courier.data

I have this model object Courier :
public class Courier {
#SerializedName("data")
private List<User> data = null;
public Courier() {
}
public Courier(List<User> data) {
this.data = data;
}
public List<User> getData() {
return data;
}
public void setData(List<User> data) {
this.data = data;
}
}
I get this response from server:
{
"data": [
{
"id": 446,
"courier": {
"data": []
},
"title": "гром",
"description": "Логойский тракт 24 в России в начале следующей",
"departure": "ChIJPQKUckNv2UYRLr1NasgXZ08",
"arrival": "EkHQodC10YDQtdCx0YDRj9C90YvQuSDQv9C10YDQtdGD0LvQvtC6LCDQnNC-0YHQutCy0LAsINCg0L7RgdGB0LjRjw"
},
{
"id": 438,
"courier": {
"data": []
},
"title": "тест",
"description": "гппг лмш ш ш ш ш г У меня на сковородке стоит ли брать сва в кино мы все равно обсуждаем",
"departure": "ChIJH10nmDnP20YR-n7Kq6Whd5w",
"arrival": "Ej_QnNC-0YHQutCy0L7RgNC10YbQutCw0Y8g0YPQu9C40YbQsCwg0JzQvtGB0LrQstCwLCDQoNC-0YHRgdC40Y8"
},
{
"id": 439,
"courier": {
"data": []
},
"title": "лаьаьаат",
"description": "лала слат алс ал ала ал кща да аьад",
"departure": "ChIJH7D4cTnP20YRKlzSCnP6Mak",
"arrival": "Ej_QnNC-0YHQutCy0L7RgNC10YbQutCw0Y8g0YPQu9C40YbQsCwg0JzQvtGB0LrQstCwLCDQoNC-0YHRgdC40Y8"
},
{
"id": 442,
"courier": {
"data": {
"id": 122,
"email": null,
"phone": "73339999999",
"photo": null,
"rating": 0
}
},
"title": "картошечка",
"description": "Крупная сортированная",
"departure": "ChIJnZRv1jnP20YRWiezW55d1tA",
"arrival": "ChIJpfH6UJtp1EYRlhM20g-jzF4"
}
]
}
If object courier not have data, i get array "data": [], if object courier has data, i get object :
"courier": {
"data": {
"id": 122,
"email": null,
"phone": "73339999999",
"photo": null,
"rating": 0
}
}
And then I get error... Please give me advice how handle this case in android application...
is one of the most common mistakes when you start to use JSON with a client, for android please refer to this tutorial to understand
the best source to understand this kind of mistake is to read this post
a canonical SO post.
Is better to read it and understand it, that asking for a simple solution because you will go really often into this error.
while deserializing, Gson was expecting a JSON object, but found a
JSON array
A JSON Object is wrapped by a {
A JSON Array is wrapped by a [
What you need is to adapt your class Courier, to deserialize in the right way the JSON response.
take in mind that; a JSON array become deserialized in java as a Collection type or an array type;
PLEASE notice that is confusing to use two times data
on top of everything, the first data is
public class MyPojo
{
private Data[] data;
public Data[] getData ()
{
return data;
}
public void setData (Data[] data)
{
this.data = data;
}
#Override
public String toString()
{
return "ClassPojo [data = "+data+"]";
}
}
Data.class
public class Data
{
private String id;
private String title;
private String description;
private Courier courier;
private String arrival;
private String departure;
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public String getTitle ()
{
return title;
}
public void setTitle (String title)
{
this.title = title;
}
public String getDescription ()
{
return description;
}
public void setDescription (String description)
{
this.description = description;
}
public Courier getCourier ()
{
return courier;
}
public void setCourier (Courier courier)
{
this.courier = courier;
}
public String getArrival ()
{
return arrival;
}
public void setArrival (String arrival)
{
this.arrival = arrival;
}
public String getDeparture ()
{
return departure;
}
public void setDeparture (String departure)
{
this.departure = departure;
}
#Override
public String toString()
{
return "ClassPojo [id = "+id+", title = "+title+", description = "+description+", courier = "+courier+", arrival = "+arrival+", departure = "+departure+"]";
}
}
Courier.class
public class Courier
{
private String[] data;
public String[] getData ()
{
return data;
}
public void setData (String[] data)
{
this.data = data;
}
#Override
public String toString()
{
return "ClassPojo [data = "+data+"]";
}
}
I suggest you just to create a class Data with fields id, email, etc. And make field Data data in the class Courier instead of a List<> data
EDIT: then you can use a JsonDeserializer. Just remove #SerializedName("data") over the Data field, so that the Json will not parse this field. Then create a class:
public class CourierDeserializer implements JsonDeserializer<Courier> {
#Override
public Courier deserialize(final JsonElement json, final Type type,
final JsonDeserializationContext context) {
Courier result = new Gson().fromJson(json, Courier.class);
try {
if (json != null) {
result.setData((Data) context.deserialize(json, Data.class));
}
} catch (JsonParseException e) {
result.setData(null);
}
return result;
}
}
and finally register it where you create your GsonBuilder:
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(Courier.class, new CourierDeserializer());
mGson = gson.create();
builder.setConverter(new GsonConverter(mGson));
if you use Retrofit.

GSON parsing for changing json data

I am parsing a JSON data using GSON library and the issue what I am facing is, a part of my json data keeps changing below is how my JSON data looks.
{
"body": [{
"result": [
{
"EndTime": "1411495899000",
"StartTime": "1411495360000"
},
{
"EndTime": "1411495359000",
"StartTime": "1411494784000"
}],
"rule": {
"ruleid": "73B5EEB4"
}
},
{
"result": [
{
"noOfErrors": "5",
"severity": "high"
},
{
"noOfErrors": "4",
"severity": "low"
}],
"rule": {
"ruleid": "35B5EEB4"
}
}
],
"header": {
"contentver": "5.5"
}
}
So in the above JSON data the result array content keeps changing based on the ruleid and I want to choose the java bean for result content at runtime based on the ruleid. Any idea?
-Regards
Well, this is going to be a long answer ...
You could use a custom JsonDeserializer to deserialize the variable part of the json string based on the ruleid.
public class MessageAdapter implements JsonDeserializer<Message> {
private Map<String, Class<? extends Result>> ruleToResultClassMap;
public MessageAdapter() {
this.ruleToResultClassMap = new HashMap<String, Class<? extends Result>>();
ruleToResultClassMap.put("73B5EEB4", DurationResults.class);
ruleToResultClassMap.put("35B5EEB4", ErrorResults.class);
}
#java.lang.Override
public Message deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject messageObject = json.getAsJsonObject();
JsonArray bodyArray = messageObject.getAsJsonArray("body");
List<Result> results = new ArrayList<Result>();
for (JsonElement bodyElement : bodyArray) {
JsonObject resultObject = bodyElement.getAsJsonObject();
JsonObject ruleObject = resultObject.getAsJsonObject("rule");
String ruleId = ruleObject.getAsJsonPrimitive("ruleid").getAsString();
Class<? extends Result> resultClass = ruleToResultClassMap.get(ruleId);
if (resultClass != null) {
Result result = context.deserialize(resultObject, resultClass);
results.add(result);
} else {
throw new IllegalArgumentException("Illegal ruleId: " + ruleId);
}
}
return new Message(results, context.<Header>deserialize(messageObject.getAsJsonObject("header"), Header.class));
}
}
You need to register the custom deserializer with GsonBuilder:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Message.class, new MessageAdapter());
Gson gson = gsonBuilder.create();
String jsonString = null; // your json string
Message message = gson.fromJson(jsonString, Message.class);
Here Message is the root POJO of the json string, you probably have your own. For full reference, I include all classes here:
public class Message {
private List<? extends Result> body;
private Header header;
public Message(List<? extends Result> body, Header header) {
this.body = body;
this.header = header;
}
public List<? extends Result> getBody() {
return body;
}
public Header getHeader() {
return header;
}
}
public class Header {
private String contentver;
public Header(String contentVer) {
this.contentver = contentVer;
}
public String getContentVer() {
return contentver;
}
}
public interface Result {
public Rule getRule();
}
public final class Rule {
private String ruleid;
public String getRuleid() {
return ruleid;
}
}
public class DurationResults implements Result {
private Duration[] result;
private Rule rule;
public Duration[] getResult() {
return result;
}
#Override
public Rule getRule() {
return rule;
}
public static final class Duration {
private long EndTime;
private long StartTime;
public long getStartTime() {
return StartTime;
}
public long getEndTime() {
return EndTime;
}
}
}
public class ErrorResults implements Result {
private Error[] result;
private Rule rule;
public Error[] getResult() {
return result;
}
#Override
public Rule getRule() {
return rule;
}
public static final class Error {
private int noOfErrors;
private String severity;
public int getNoOfErrors() {
return noOfErrors;
}
public String getSeverity() {
return severity;
}
}
}
I think you have to parse your json if your result change.
Replace first "result" to "FirstResult" , and replace second "result" to "SecondResult".
Your json have to look like this:
{
"body": [{
"FirstResult": [
{
"EndTime": "1411495899000",
"StartTime": "1411495360000"
},
{
"EndTime": "1411495359000",
"StartTime": "1411494784000"
}],
"rule": {
"ruleid": "73B5EEB4"
}
},
{
"SecondResult": [
{
"noOfErrors": "5",
"severity": "high"
},
{
"noOfErrors": "4",
"severity": "low"
}],
"rule": {
"ruleid": "35B5EEB4"
}
}
],
"header": {
"contentver": "5.5"
}
}
And you can parse json to Java Objects. If you have first result parse to FirstResultObject.java , if you have second result parse to SecondResult.java
SecondResult.java
public class SecondResult
{
private String noOfErrors;
private String severity;
public String getNoOfErrors ()
{
return noOfErrors;
}
public void setNoOfErrors (String noOfErrors)
{
this.noOfErrors = noOfErrors;
}
public String getSeverity ()
{
return severity;
}
public void setSeverity (String severity)
{
this.severity = severity;
}
}
FirstResult.java
public class FirstResult
{
private String EndTime;
private String StartTime;
public String getEndTime ()
{
return EndTime;
}
public void setEndTime (String EndTime)
{
this.EndTime = EndTime;
}
public String getStartTime ()
{
return StartTime;
}
public void setStartTime (String StartTime)
{
this.StartTime = StartTime;
}
}

Categories

Resources