JSON Conversion to Java Object - java

I was trying to parse the following string from Python into Java Object, but the Java Object that I have created for it shows the properties as null I could see the id part of it not the other properties.
Please find the Java Class below:
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
#JsonProperty("remote-system-desc")
public String getRemote_system_desc()
{
return remote_system_desc;
}
#JsonProperty("remote-system-desc")
public void setRemote_system_desc(String remote_system_desc)
{
this.remote_system_desc = remote_system_desc;
}
#JsonProperty("remote-system-capabilities")
public String getRemote_system_capabilities()
{
return remote_system_capabilities;
}
#JsonProperty("remote-system-capabilities")
public void setRemote_system_capabilities(String remote_system_capabilities)
{
this.remote_system_capabilities = remote_system_capabilities;
}
#JsonProperty("remote-chassis-id")
public String getRemote_chassis_id()
{
return remote_chassis_id;
}
#JsonProperty("remote-chassis-id")
public void setRemote_chassis_id(String remote_chassis_id)
{
this.remote_chassis_id = remote_chassis_id;
}
public List<ExternalSwitchPort> getPorts()
{
return ports;
}
public void setPorts(List<ExternalSwitchPort> ports)
{
this.ports = ports;
}
#JsonProperty("remote-system-name")
public String getRemote_system_name()
{
return remote_system_name;
}
#JsonProperty("remote-system-name")
public void setRemote_system_name(String remote_system_name)
{
this.remote_system_name = remote_system_name;
}
"externalSwitches": [{"id": "00:15:60:00:eb:80", "remote-system-desc": "ProCurve J4904A Switch 2848, revision I.10.77, ROM I.08.07 (/sw/code/build/mako(mkfs))", "remote-system-capabilities": "bridge,router", "remote-chassis-id": "00:15:60:00:eb:80", "ports": [{"remote-port-desc": "33", "id": "enc0:iobay2:X5", "remote-port-id": "33"}], "remote-system-name": "VirtSW Rack9"}, {"id": "00:13:21:dd:35:00", "remote-system-desc": "ProCurve J4904A Switch 2848, revision I.10.77, ROM I.08.07 (/sw/code/build/mako(mkfs))", "remote-system-capabilities": "bridge,router", "remote-chassis-id": "00:13:21:dd:35:00", "ports": [{"remote-port-desc": "19", "id": "enc0:iobay1:X5", "remote-port-id": "19"}], "remote-system-name": "swr5-hpqcorp"}]}
I am not able to find out whether it's due to the data content or because it's not able to properly parse the properties remote-system-desc but I have mentioned that in the JSON property.

Related

Parsing JSON array with Array of objects inside with Retrofit

i have this fragment of a json response from an endpoint in where i need to get some news, but is kinda returning me wrong info or maybe i'm doing this wrong:
{
"data": [
{
"alignImages": "left",
"data": [
{
"content": "Despus de dos aos de la operacin y una intensiva terapia, jvenes que no podan mover sus miembros inferiores y superiores ahora pueden comer, cepi",
"id": 179,
"title": "Ciruga que reconecta los nervios le devolvi a 13 tetrapljicos la movilidad en",
"url_detail": "https://www.elespectador.com/noticias/salud/cirugia-que-reconecta-los-nervios-le-devolvio-13-tetraplejicos-la-movilidad-en-brazos-y-codos-articulo-869",
"url_image": "https://storage.googleapis.com/sitidoctor-161813.appspot.com/images/noticia_2.png"
},
{
...
}
],
"imgHeader": "https://storage.googleapis.com/sitidoctor-161813.appspot.com/images/Noticias_Salud.png",
"titleHeader": "Noticias Salud"
}
],
"message": "success!",
"status": 200
}
This is the model i use to parse the response from the retrofit instance query:
public class NewsResponse {
#SerializedName("data")
#Expose
private List<New> data = null;
#SerializedName("message")
#Expose
private String message;
#SerializedName("status")
#Expose
private Integer status;
public List<New> getData() {
return data;
}
public void setData(List<New> data) {
this.data = data;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
and i make the request using retrofit like this:
private void handleResponse(NewsResponse newsResponse) {
Log.e("response", newsResponse.getData().toString());
if (newsResponse.getData().size() > 0){
List<New> n = new ArrayList<>();
for (int i = 0; i < newsResponse.getData().size(); i++){
New nn = newsResponse.getData().get(i);
n.add(nn);
}
callback.onSuccess(n);
}
}
but i'm always getting the a single and empty value, is like is returning the inner data array as object but cant get data, i tried everything and got nothing, any ideas?
Reference imagen in debugger
Looking into your debugger image, Your newsResponse.getData().size() is 1. The only element in the list has id,title,content, uridetail as null. You are handling the response correctly. There is something wrong with your response. Please check if you are making the network call correctly

How to Solve Deserialization error ask sdk

I'm attempting to convert the JSON output from my session and map it to a class that I've created using JAVA's ObjectMapper. When I run my tests on Lambda I get a Deserialisation error:
Deserialization error: com.amazon.ask.exception.AskSdkException
com.amazon.ask.exception.AskSdkException: Deserialization error
at com.amazon.ask.util.impl.JacksonJsonUnmarshaller.unmarshall(JacksonJsonUnmarshaller.java:50)
at com.amazon.ask.impl.AbstractSkill.execute(AbstractSkill.java:44)
at com.amazon.ask.AlexaSkill.execute(AlexaSkill.java:22)
at com.amazon.ask.SkillStreamHandler.handleRequest(SkillStreamHandler.java:71)
Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'AnswerIntent' as a subtype of [simple type, class com.amazon.ask.model.Request]: known type ids = [Alexa.Presentation.APL.UserEvent, AlexaHouseholdListEvent.ItemsCreated, AlexaHouseholdListEvent.ItemsDeleted, AlexaHouseholdListEvent.ItemsUpdated, AlexaHouseholdListEvent.ListCreated, AlexaHouseholdListEvent.ListDeleted, AlexaHouseholdListEvent.ListUpdated, AlexaSkillEvent.SkillAccountLinked, AlexaSkillEvent.SkillDisabled, AlexaSkillEvent.SkillEnabled, AlexaSkillEvent.SkillPermissionAccepted, AlexaSkillEvent.SkillPermissionChanged, AudioPlayer.PlaybackFailed, AudioPlayer.PlaybackFinished, AudioPlayer.PlaybackNearlyFinished, AudioPlayer.PlaybackStarted, AudioPlayer.PlaybackStopped, Connections.Request, Connections.Response, Display.ElementSelected, GameEngine.InputHandlerEvent, IntentRequest, LaunchRequest, Messaging.MessageReceived, PlaybackController.NextCommandIssued, PlaybackController.PauseCommandIssued, PlaybackController.PlayCommandIssued, PlaybackController.PreviousCommandIssued, SessionEndedRequest, System.ExceptionEncountered] (for POJO property 'request')
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.amazon.ask.model.RequestEnvelope$Builder["request"])
at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
at com.fasterxml.jackson.databind.DeserializationContext.invalidTypeIdException(DeserializationContext.java:1628)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownTypeId(DeserializationContext.java:1186)
at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._handleUnknownTypeId(TypeDeserializerBase.java:291)
at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:162)
at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:113)
at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:97)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:254)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:151)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.vanillaDeserialize(BuilderBasedDeserializer.java:269)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:193)
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3972)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2264)
at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:2746)
at com.amazon.ask.util.impl.JacksonJsonUnmarshaller.unmarshall(JacksonJsonUnmarshaller.java:48)
... 3 more
I did checks to ensure that my "riddleItem" variable is not null. The JSON values are being mapped to the Person class which just returns properties of a person. The code is shown below and I've highlighted the line which the error occurs on:
public Optional<Response> handle(HandlerInput input) {
Map<String, Object> sessionAttributes = input.getAttributesManager().getSessionAttributes();
System.out.println("This a FIRST debug");
LOG.debug("This a FIRST debug");
boolean correctAnswer;
String speechText = null, response;
System.out.println("This a SECOND debug");
Map<String, String> riddleItem = (LinkedHashMap<String, String>)sessionAttributes.get(Attributes.RIDDLE_ITEM_KEY);
Person person;
// System.out.println("riddleItem " + riddleItem);
if(riddleItem != null)
{
person = MAPPER.convertValue(riddleItem, Person.class); // ERROR OCCURS ON THIS LINE
}
System.out.println("This a THIRD debug");
PersonProperty personProperty = PersonProperty.valueOf((String) sessionAttributes.get(Attributes.RIDDLE_PROPERTY_KEY));
int counter = (int) sessionAttributes.get(Attributes.COUNTER_KEY);
int riddleGameScore = (int) sessionAttributes.get(Attributes.RIDDLE_SCORE_KEY);
System.out.println("This a FOURTH debug");
IntentRequest intentRequest = (IntentRequest) input.getRequestEnvelope().getRequest();
correctAnswer = compareSlots(intentRequest.getIntent().getSlots(), getPropertyOfPerson(personProperty, person));
System.out.println("This a FIFTH debug " + correctAnswer);
if(correctAnswer)
{
riddleGameScore++;
response = getSpeechExpressionCon(true);
System.out.println("This a SIXTH debug " + response);
sessionAttributes.put(Attributes.RIDDLE_SCORE_KEY, riddleGameScore);
}
else
{
response = getSpeechExpressionCon(false);
System.out.println("This a SEVENTH debug " + response);
}
AnswerIntentHandler setup = new AnswerIntentHandler();
//
if(riddle.getAnswer() != null)
{
speechText = "Hello " + riddle.getAnswer();
}
return input.getResponseBuilder()
.withSimpleCard("RiddleSession", speechText)
.withSpeech(speechText)
.withShouldEndSession(true)
.build();
}
[Json Output of properties under "riddleItem" during Session]1
I know my the values being mapped aren't empty thus I'm at a complete loss of ideas as to what's going on as I've come up short with possible ideas as to what the problem might be.
I solved the problem as I came to realise that when mapping from JSON to a class, methods ('set' methods) for assigning the JSON values to the variables in the class must be created. A sample structure for example:
public class State {
public State() {}
public State(String name, String abbreviation, String capital, String statehoodYear, String statehoodOrder) {
this.name = name;
this.abbreviation = abbreviation;
this.capital = capital;
this.statehoodYear = statehoodYear;
this.statehoodOrder = statehoodOrder;
}
public String getName() {
return name;
}
public String getAbbreviation() {
return abbreviation;
}
public String getCapital() {
return capital;
}
public String getStatehoodYear() { return statehoodYear; }
public String getStatehoodOrder() {
return statehoodOrder;
}
public void setName(String name) {
this.name = name;
}
public void setAbbreviation(String abbreviation) {
this.abbreviation = abbreviation;
}
public void setCapital(String capital) {
this.capital = capital;
}
public void setStatehoodYear(String statehoodYear) {
this.statehoodYear = statehoodYear;
}
public void setStatehoodOrder(String statehoodOrder) {
this.statehoodOrder = statehoodOrder;
}
}
The declaration of an empty constructor is necessary when making use of multiple constructors where, one is parametric. In some cases without the inclusion of such constructor an error may be thrown so, to avoid the possibility of said error, adding the constructor as a "Dummy" so to say, is essential.

JSON Post Response from JSON Post Request

I have created a REST webservice which gives me
'GET JSON Response' as :
{
"payload": {
"RFID": "E2005180040F003122202E5F",
"chassisNumber": "4654689761",
"vehicleNumber": "TN 01 1991"
},
"success": "true"
}
Now I want Post Response from below Post Request :
Vehicle tag Request
{
"vehicle_no": "TN07B0054"
}
I have created the post method but it takes the whole thing as argument.
How to take vehicle argument as "TN07B0054" only from the Vehicle tag request.
Below is the POST response when I give above Vehicle Tag Request :
{
"payload": {
"vehicleNumber": "\"vehicle_no\": \"TN 07 B 0054\""
},
"success": "false"
}
You can make a entity named VehicleTagRequest
public class VehicleTagRequest {
private String vehicle_no;
public String getVehicle_no() {
return vehicle_no;
}
public void setVehicle_no(String vehicle_no) {
this.vehicle_no = vehicle_no;
}
}
Easiest way to deserialise your string to above java object is to use Jackson library (https://github.com/FasterXML/jackson)
If you are Maven for dependency management, you can add dependency like below in your pom.xml (this step is not required if you are maintaining your dependencies locally)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0.pr4</version>
</dependency>
Now comes deserialisation of your vehicle tag request json
Deserialisation using Jackson is done using ObjectMapper API if you are not using annotations,
I have made a sample code snippet attached below-
public class VehicleSerialisation {
public static void main(String[] args) {
String vehicle = "{\"vehicle_no\": \"TN07B0054\"}";
ObjectMapper objectMapper = new ObjectMapper();
VehicleTagRequest vehicleTagRequest = null;
try {
vehicleTagRequest = objectMapper.readValue(vehicle, VehicleTagRequest.class);
} catch (IOException e) {
e.printStackTrace();
}
System.out.print(vehicleTagRequest.getVehicle_no());
}
}
You can then use the vehicleTagRequest.getVehicle_no() to form your request of GET JSON Response
This is not valid Json
{
"payload": {
"vehicleNumber": "\"vehicle_no\": \"TN 07 B 0054\""
},
"success": "false"
}
Without escape char
{
"payload": {
"vehicleNumber": "vehicle_no": "TN 07 B 0054"
},
"success": "false"
}
You can use like this
{
"payload": {
"vehicleNumber": {
"vehicle_no": "TN 07 B 0054"
}
},
"success": "false"
}
And your POJO should be like
public class MyPojo
{
private Payload payload;
private String success;
public Payload getPayload ()
{
return payload;
}
public void setPayload (Payload payload)
{
this.payload = payload;
}
public String getSuccess ()
{
return success;
}
public void setSuccess (String success)
{
this.success = success;
}
#Override
public String toString()
{
return "ClassPojo [payload = "+payload+", success = "+success+"]";
}
}

Using Retrofit to convert from to array of JSON objects to List

Greeting and Mrry Xmas,i have this array of JSON object as follows:
[{"AgencyName":"Head-Office/Branch","AgencyLocation":"Immeuble Grand Carrefour Rue Marie Gocker,Yaounde","AgencyPhoneNumber":"+237222229610/691698762","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Yaounde-Marche-Centrale Branch","AgencyLocation":"Immeuble Grand Carrefour Rue Marie Gocker,Yaounde","AgencyPhoneNumber":"+237222041661/22229604/91697426","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Bamenda Branch","AgencyLocation":"Evidence Building, City Chemist Roundabout,Bamenda","AgencyPhoneNumber":"+237222041665/233364170/691697553","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Deido Branch","AgencyLocation":"Face Boulangerie COAF, Douala","AgencyPhoneNumber":"+237222041660/633402641/691697494","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Bafut Branch","AgencyLocation":"Midland Centre, 3 Corners Njinteh, Bafut","AgencyPhoneNumber":"+237675025263/691698716","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Buea Branch","AgencyLocation":"University Junction, Molyko, Buea","AgencyPhoneNumber":" +237222041664/333323322/691698625","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Bonaberi Branch","AgencyLocation":"Cimetière, Immeuble Pharmacie Bonaberi, Douala","AgencyPhoneNumber":"+237222041663/333392710/691697617","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Biyem-Assi Branch","AgencyLocation":"Carrefour Biyem-assi ,Yaounde","AgencyPhoneNumber":"+237222041662/222316710/691698667","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Limbe Branch","AgencyLocation":"Down Beach, Sappa Road, Limbe","AgencyPhoneNumber":"+237222041690/222041693/691698628","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Kribi Branch","AgencyLocation":"Adjacent Auto Ecole Française Rue Petit Paris, Kribi","AgencyPhoneNumber":"+237222041691/222041692/691698632","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Akwa Branch","AgencyLocation":"Boulevard de la Liberté, Douala","AgencyPhoneNumber":"+237222041670/691698663","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Dakar Branch","AgencyLocation":"Marché Bilongué, Douala","AgencyPhoneNumber":"+237691698627","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Bambili Branch","AgencyLocation":"Three Corners, Bambili","AgencyPhoneNumber":"+237222054199/691697441","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Tchinga Branch","AgencyLocation":"Ave du 27 Août 1940,Yaounde","AgencyPhoneNumber":"691907381","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"},{"AgencyName":"Kumba Branch","AgencyLocation":"Kumba","AgencyPhoneNumber":"+237222041664","AgencyGPSCoordinates":"GPS Position","AgencyHours":"8:00-16:00"}]
here is the corresponding class(using jsonschema2pojo):
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class AgencyModel {
#SerializedName("AgencyName")
#Expose
private String agencyName;
#SerializedName("AgencyLocation")
#Expose
private String agencyLocation;
#SerializedName("AgencyPhoneNumber")
#Expose
private String agencyPhoneNumber;
#SerializedName("AgencyGPSCoordinates")
#Expose
private String agencyGPSCoordinates;
#SerializedName("AgencyHours")
#Expose
private String agencyHours;
public String getAgencyName() {
return agencyName;
}
public void setAgencyName(String agencyName) {
this.agencyName = agencyName;
}
public String getAgencyLocation() {
return agencyLocation;
}
public void setAgencyLocation(String agencyLocation) {
this.agencyLocation = agencyLocation;
}
public String getAgencyPhoneNumber() {
return agencyPhoneNumber;
}
public void setAgencyPhoneNumber(String agencyPhoneNumber) {
this.agencyPhoneNumber = agencyPhoneNumber;
}
public String getAgencyGPSCoordinates() {
return agencyGPSCoordinates;
}
public void setAgencyGPSCoordinates(String agencyGPSCoordinates) {
this.agencyGPSCoordinates = agencyGPSCoordinates;
}
public String getAgencyHours() {
return agencyHours;
}
public void setAgencyHours(String agencyHours) {
this.agencyHours = agencyHours;
}
}
I'am using retrofit2 to get the list of objects,ive looked abit # the documentation and examples but still i have error,here is my Api class:
public static UnicsAgencyApi getUnicsAgencyApi() {
if (sUnicsAgencyApi == null) {
retrofit = new Retrofit.Builder().baseUrl(ENDPOINT_URL).addConverterFactory(GsonConverterFactory.create())
.build();
sUnicsAgencyApi = retrofit.create(UnicsAgencyApi.class);
}
return sUnicsAgencyApi;
}
public interface UnicsAgencyApi {
#GET("api/uconnectservice/AllAgency")
void getStreams(Callback<List<AgencyModel>> callback);
}
and here is where i make the request:
RestApi.getUnicsAgencyApi().getStreams(new Callback <List<AgencyModel>>(){
#Override
public void onFailure(Call<List<AgencyModel>> arg0, Throwable arg1) {
// TODO Auto-generated method stub
}
#Override
public void onResponse(Call<List<AgencyModel>> AgencyModelData, Response<List<AgencyModel>> response) {
// TODO Auto-generated method stub
//ConsumeApiData(response);
**mstreamData.addAll(response);**
}
});
the error occurs # mstreamData.addAll(response); I don't know what i did wrong,pls any one there with any suggestion or better of doing this i greatly appreciated
cheers
Use response.body(). In your code you'd have
mstreamData.addAll(response.body());

How to parse JSON Response with GSON (Java / Android)

I just need a quick advice, as i am a total beginner with JSON.
I get the following response from a webserver, which i store in a String:
{
"station62":[
{
"departureTime":1982,
"delay":"-1.0",
"line":"6",
"stationName":"randomname",
"direction":2
}
],
"station63":[
{
"departureTime":1234,
"delay":"-1.0",
"line":"87",
"stationName":"anotherrandomname",
"direction":2
}
],
"station64":[
{
"departureTime":4542,
"delay":"-1.0",
"line":"4",
"stationName":"yetanotherrandomname",
"direction":2
}
],
"station65":[
{
"departureTime":1232,
"delay":"-1.0",
"line":"23",
"stationName":"onemorerandomname",
"direction":2
}
]
}
(Sorry, i dont know how the indent works on here.)
The response is longer, but for this example it is shortened. So what i need is to parse the information of each of these "station"-objects.
I dont need the "station62"-String, i only need "departureTime", "delay", "line", "stationName" and "direction" in a java-object.
I have read this, but i couldnt make it work: https://stackoverflow.com/a/16378782
I am a total beginner, so any help would be really appreciated.
Edit: Here is my code:
I made a wrapper class just like in the example link above. I played with the map types a bit, but no luck so far.
public class ServerResponse
{
private Map<String, ArrayList<Station>> stationsInResponse = new HashMap<String, ArrayList<Station>>();
public Map<String, ArrayList<Station>> getStationsInResponse()
{
return stationsInResponse;
}
public void setStationsInResponse(Map<String, ArrayList<Station>> stationsInResponse)
{
this.stationsInResponse = stationsInResponse;
}
}
The problem is, that this map does not get filled by the gson.fromJSON(...)-call i am showing below. The map size is always zero.
Station class looks like this:
public class Station
{
String line;
String stationName;
String departureTime;
String direction;
String delay;
// getters and setters are there aswell
}
And what i am trying to do is
Gson gson = new Gson();
ServerResponse response = gson.fromJson(jsonString, ServerResponse.class);
where "jsonString" contains the JSON response as a string.
I hope that code shows what i need to do, it should be pretty simple but i am just not good enough in JSON.
EDIT 2
Would i need my JSON to be like this?
{"stationsInResponse": {
"station62": [{
"departureTime": 1922,
"delay": "-1.0",
"line": "8",
"stationName": "whateverrandomname",
"direction": 2
}],
"station67": [{
"departureTime": 1573,
"delay": "-1.0",
"line": "8",
"stationName": "rndmname",
"direction": 2
}],
"station157": [{
"departureTime": 1842,
"delay": "-2.0",
"line": "8",
"stationName": "randomname",
"direction": 2
}]
}}
Here is the working code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
public class GSONTest {
public static void main(String[] args){
String gsonStr = "{\"stationsInResponse\": { \"station62\":[ { \"departureTime\":1982,\"delay\":\"-1.0\",\"line\":\"6\",\"stationName\":\"randomname\",\"direction\":2} ],\"station63\":[ { \"departureTime\":1981,\"delay\":\"-1.1\",\"line\":\"7\",\"stationName\":\"randomname2\",\"direction\":3} ]}}";
Gson gson = new Gson();
Response response = gson.fromJson(gsonStr, Response.class);
System.out.println("Map size:"+response.getStationsInResponse().size());
for (Iterator iterator = response.getStationsInResponse().keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
ArrayList<Station> stationList = (ArrayList<Station>) response.getStationsInResponse().get(key);
for (Iterator iterator2 = stationList.iterator(); iterator2.hasNext();) {
Station station = (Station) iterator2.next();
System.out.println("Delay: "+station.getDelay());
System.out.println("DepartureTime: "+station.getDepartureTime());
System.out.println("Line: "+station.getLine());
System.out.println("StationName: "+station.getStationName());
}
}
}
}
class Response {
private Map<String, List<Station>> stationsInResponse;
//getters and setters
public Map<String, List<Station>> getStationsInResponse() {
return stationsInResponse;
}
public void setStationsInResponse(Map<String, List<Station>> stationsInResponse) {
this.stationsInResponse = stationsInResponse;
}
}
class Station {
private String departureTime;
public String getDepartureTime() {
return departureTime;
}
public void setDepartureTime(String departureTime) {
this.departureTime = departureTime;
}
public String getDelay() {
return delay;
}
public void setDelay(String delay) {
this.delay = delay;
}
public String getLine() {
return line;
}
public void setLine(String line) {
this.line = line;
}
public String getStationName() {
return stationName;
}
public void setStationName(String stationName) {
this.stationName = stationName;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
private String delay;
private String line;
private String stationName;
private String direction;
}
Output in console is like this(as I shortened your json string):
Map size:2
Delay: -1.0
DepartureTime: 1982
Line: 6
StationName: randomname
Delay: -1.1
DepartureTime: 1981
Line: 7
StationName: randomname2
First I'll point out your mistake, then I'll give you the solution.
The structure you're asking for in your deserialization code looks like this:
{
"stationsInResponse": {
"station1": [
{
"name": "Station 1"
}
],
"station2": [
{
"name": "Station 2"
}
]
}
}
Solution
The deserialization code you really need to deserialize the structure you're getting as input, is as follows:
Gson gson = new Gson();
Type rootType = new TypeToken<Map<String, List<Station>>>(){}.getType();
Map<String, List<Station>> stationsMap = gson.fromJson(json, rootType);
This is because a JSON object, whose properties are unknown at compile-time, which your root object is, maps to a Java Map<String, ?>. The ? represent the expected Java type of the JSON object value, which in your case is either List<Station> or Station[], whichever you prefer.
If you wanted to, you could combine all the stations in the map into one List of stations like so:
List<Station> stations = new ArrayList<>(stationsMap.size());
for (List<Station> stationsList : stationsMap.values()) {
for (Station station : stationsList) {
stations.add(station);
}
}

Categories