stucked at accessing nested json. similar stuff:
[
{
key-value,
key-value
},
{
key-value,
key-value
},
{
key-value,
key-value
}
]
works nicely but when i try:
{
"alfa":{
"id":"foo",
"product":{
"id":"foo1",
"price":"foo2"
}
},
"beta":{
"id":"foo",
"product":{
"id":"foo1",
"price":"foo2"
}
}
}
i get error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<...
i of course did change structure of classes:
public class Alphabet{
private Purchase purchase;
...
public class Purchase{
private String id;
private Product product;
...
public class Product {
private String id;
private String price;
...
to read it:
ObjectMapper mapper = new ObjectMapper();
InputStream inputStream = new FileInputStream(new File("src/main/json/file.json"));
TypeReference<List<Alphabet>> typeReference = new TypeReference<List<Alphabet>>() {};
List<Alphabet> alphabet= mapper.readValue(inputStream, typeReference);
System.out.println(alphabet);
whats wrong, please?
It seems like the JSON structure you try to read is not a List<Alphabet>, but a Map<String, Purchase>.
Your second json not like list of object. The second json look lik have 2 main objects if so you need class like below.
public class Alphabet{
private Purchase purchase;
private Purchase purchase1;
}
But it not good practice. Use as first josn like list of objects.
I'm consuming an external API, for which a JSON Object is returned. Contained in that Object response is an array that I need to extract and set to a List of a particular entity type. Java, however, is not a language that I'm very familiar with, so I'm having problems attempting to figure this out.
I've created a type of wrapper class to work with this in the setter.
The best I've come up with that compiles is below, but produces an error that I can't figure out.
public void setFlights(Object responseBody) {
String responseString = responseBody.toString();
JSONObject responseJSONObject = new JSONObject(responseString);
JSONArray responseJSONArray = responseJSONObject.getJSONArray("flights");
Gson gson = new Gson();
Type flightType = new TypeToken<List<Flight>>() {}.getType();
this.flights = gson.fromJson(String.valueOf(responseJSONArray), flightType);
}
As you can see, I'm kind of throwing it at the wall to see if it will stick. I'm trying to use Gson to get around some of the Type issues I've come across.
The error produced when executing is:
org.json.JSONException: Expected a ':' after a key at 7 [character 8 line 1]
Response String is as follows:
Response String Image
If that's difficult to deal with, here's the response in text:
INFO: {"FlightInfoResult":{"next_offset":-1,"flights":[{"ident":"N1RJ","aircrafttype":"HDJT","filed_ete":"01:25:00","filed_time":1593038253,"filed_departuretime":1593037500,"filed_airspeed_kts":400,"filed_airspeed_mach":"","filed_altitude":360,"route":"WEAZL4 CLAWD","actualdeparturetime":1593038285,"estimatedarrivaltime":1593043320,"actualarrivaltime":1593043320,"diverted":"","origin":"KJQF","destination":"KJXN","originName":"Concord-Padgett Rgnl","originCity":"Concord, NC","destinationName":"Jackson County","destinationCity":"Jackson, MI"},{"ident":"N1RJ","aircrafttype":"HDJT","filed_ete":"01:24:00","filed_time":1593000320,"filed_departuretime":1592998200,"filed_airspeed_kts":400,"filed_airspeed_mach":"","filed_altitude":350,"route":"PEGTE","actualdeparturetime":1593000420,"estimatedarrivaltime":1593005149,"actualarrivaltime":1593005149,"diverted":"","origin":"KJXN","destination":"KJQF","originName":"Jackson County","originCity":"Jackson, MI","destinationName":"Concord-Padgett Rgnl","destinationCity":"Concord, NC"},{"ident":"N1RJ","aircrafttype":"HDJT","filed_ete":"01:29:00","filed_time":1592518049,"filed_departuretime":1592513400,"filed_airspeed_kts":317,"filed_airspeed_mach":"","filed_altitude":360,"route":"WEAZL4 CLAWD","actualdeparturetime":1592517936,"estimatedarrivaltime":1592523120,"actualarrivaltime":1592523120,"diverted":"","origin":"KJQF","destination":"KJXN","originName":"Concord-Padgett Rgnl","originCity":"Concord, NC","destinationName":"Jackson County","destinationCity":"Jackson, MI"},{"ident":"N1RJ","aircrafttype":"HDJT","filed_ete":"01:24:00","filed_time":1592481020,"filed_departuretime":1592479800,"filed_airspeed_kts":319,"filed_airspeed_mach":"","filed_altitude":350,"route":"PEGTE","actualdeparturetime":1592481126,"estimatedarrivaltime":1592486100,"actualarrivaltime":1592486100,"diverted":"","origin":"KJXN","destination":"KJQF","originName":"Jackson County","originCity":"Jackson, MI","destinationName":"Concord-Padgett Rgnl","destinationCity":"Concord, NC"}]}}
There very well may be a much more simple way of accomplishing what I need. Any example help is very much appreciated.
You can use Gson string to object mapper class directly as like below,
package com.sample.programs;
import java.util.List;
import com.google.gson.Gson;
public class FlightInfoResultMain {
public static void main(String[] args) {
String input = "{\"FlightInfoResult\":{\"next_offset\":-1,\"flights\":[{\"ident\":\"N1RJ\",\"aircrafttype\":\"HDJT\",\"filed_ete\":\"01:25:00\",\"filed_time\":1593038253,\"filed_departuretime\":1593037500,\"filed_airspeed_kts\":400,\"filed_airspeed_mach\":\"\",\"filed_altitude\":360,\"route\":\"WEAZL4 CLAWD\",\"actualdeparturetime\":1593038285,\"estimatedarrivaltime\":1593043320,\"actualarrivaltime\":1593043320,\"diverted\":\"\",\"origin\":\"KJQF\",\"destination\":\"KJXN\",\"originName\":\"Concord-Padgett Rgnl\",\"originCity\":\"Concord, NC\",\"destinationName\":\"Jackson County\",\"destinationCity\":\"Jackson, MI\"},{\"ident\":\"N1RJ\",\"aircrafttype\":\"HDJT\",\"filed_ete\":\"01:24:00\",\"filed_time\":1593000320,\"filed_departuretime\":1592998200,\"filed_airspeed_kts\":400,\"filed_airspeed_mach\":\"\",\"filed_altitude\":350,\"route\":\"PEGTE\",\"actualdeparturetime\":1593000420,\"estimatedarrivaltime\":1593005149,\"actualarrivaltime\":1593005149,\"diverted\":\"\",\"origin\":\"KJXN\",\"destination\":\"KJQF\",\"originName\":\"Jackson County\",\"originCity\":\"Jackson, MI\",\"destinationName\":\"Concord-Padgett Rgnl\",\"destinationCity\":\"Concord, NC\"},{\"ident\":\"N1RJ\",\"aircrafttype\":\"HDJT\",\"filed_ete\":\"01:29:00\",\"filed_time\":1592518049,\"filed_departuretime\":1592513400,\"filed_airspeed_kts\":317,\"filed_airspeed_mach\":\"\",\"filed_altitude\":360,\"route\":\"WEAZL4 CLAWD\",\"actualdeparturetime\":1592517936,\"estimatedarrivaltime\":1592523120,\"actualarrivaltime\":1592523120,\"diverted\":\"\",\"origin\":\"KJQF\",\"destination\":\"KJXN\",\"originName\":\"Concord-Padgett Rgnl\",\"originCity\":\"Concord, NC\",\"destinationName\":\"Jackson County\",\"destinationCity\":\"Jackson, MI\"},{\"ident\":\"N1RJ\",\"aircrafttype\":\"HDJT\",\"filed_ete\":\"01:24:00\",\"filed_time\":1592481020,\"filed_departuretime\":1592479800,\"filed_airspeed_kts\":319,\"filed_airspeed_mach\":\"\",\"filed_altitude\":350,\"route\":\"PEGTE\",\"actualdeparturetime\":1592481126,\"estimatedarrivaltime\":1592486100,\"actualarrivaltime\":1592486100,\"diverted\":\"\",\"origin\":\"KJXN\",\"destination\":\"KJQF\",\"originName\":\"Jackson County\",\"originCity\":\"Jackson, MI\",\"destinationName\":\"Concord-Padgett Rgnl\",\"destinationCity\":\"Concord, NC\"}]}}";
System.out.println("input - " + input);
//Create Gson object
Gson gson = new Gson();
FlightInfoResultObject responseObject = gson.fromJson(input, FlightInfoResultObject.class);
// parsing response to java pojo
List<Flights> listOfFlights = responseObject.getFlightInfoResult().getFlights();
for (Flights flight : listOfFlights) {
System.out.println("flight - " + flight.getIdent());
}
}
}
Object Mapping class: Inside Flights.class you can add all the variable which you have in json response.
class FlightInfoResultObject {
FlightInfoResult FlightInfoResult;
#Getter
#Setter
}
class FlightInfoResult {
Integer next_offset;
List<Flights> flights;
#Getter
#Setter
}
class Flights {
String ident;
String aircrafttype;
#Getter
#Setter
}
I think it's impossible to retrieve the inner JSON element directly using gson.
You have to get FlightInfoResult then flights accordingly. This should work:
Gson gson = new Gson();
JsonObject jsonObject = com.google.gson.JsonParser.parseString(responseString).getAsJsonObject();
JsonArray flightArray = jsonObject.getAsJsonObject("FlightInfoResult").getAsJsonArray("flights");
Type flightType = new TypeToken<List<Flight>>() {}.getType();
List<Flight> flights = gson.fromJson(flightArray, flightType);
Anyway, make sure the name of all properties inside class Flight matches Json elements name, to avoid mapping errors.
Since you didn't post your Flight class definition and gson naming rule, but the Flight class should be like:
public class Flight {
private String ident;
private String aircrafttype;
private String filed_ete;
private float filed_time;
private float filed_departuretime;
private float filed_airspeed_kts;
private String filed_airspeed_mach;
private float filed_altitude;
private String route;
private float actualdeparturetime;
private float estimatedarrivaltime;
private float actualarrivaltime;
private String diverted;
private String origin;
private String destination;
private String originName;
private String originCity;
private String destinationName;
private String destinationCity;
// getters setters
How can I convert the JSON string like this:
{ "summary": {
"totalMR":4.599000000000903E12,
"totalMA":1.9174920000386694E11,
"totalQA":5.1111111181E9,
"totalQR":1.000020666115264E11
},
"result": [{},{}],
"success":"true",
"total":49
}
to a Java object. I went through many similar posts and implemented constructors but couldn't find the proper explanation of why I'm unable to De-serialize the JSON.
Am I doing anything wrong?
My Class:
public class expResponse {
private String success;
private String total;
private ArrayList<LinkedHashMap<String,Object>> result;
private LinkedHashMap<String,SummaryResponse> summary;
// Constructor: public expResponse(){}
// Getter and Setter
}
public class SummaryResponse {
private Float totalQR;
private Float totalQA;
private Float totalMR;
private Float totalMA;
public SummaryResponse(){}
// Setter and Getter
}
My Code:
private expResponse processResult(String result) throws IOException{
ObjectMapper objectMapper = new ObjectMapper();
expResponse expResponseObj =
objectMapper.readValue(result, expResponse.class);
return expResponseObj;
The json you posted would not deserialize into a map of SummaryResponse objects, but rather an individual SummaryResponse object. To make your binding work, you would have to have json that looked something like this:
{
...
'summary': {
'summary1': {"totalMR":4.599000000000903E12,"totalMA":1.9174920000386694E11,"totalQA":5.1111111181E9,"totalQR":1.000020666115264E11}
'summary2': {"totalMR":4.599000000000903E12,"totalMA":1.9174920000386694E11,"totalQA":5.1111111181E9,"totalQR":1.000020666115264E11}
}
...
}
Alternatively, if you need to make your Java class conform to the json you provided, you simply need to change the declaration of summary:
private SummaryResponse summary;
Field summary in your json is an object of type SummaryResponse and not a LinkedHashMap.
public class ExpResponse {
private String success;
private String total;
private ArrayList<LinkedHashMap<String,Object>> result;
private Summary summary;
}
I don't think you have a problem in the code. Your input fails because it is not in the correct format. If you try to write the same values from an object with the same values to string you get something like:
{
"success":"true",
"total":"49",
"result":null,
"summary":{
"one_summary":{
"totalQR":2000.0,
"totalQA":1500.0,
"totalMR":1000.0,
"totalMA":500.0
}
}
}
And the major difference is the one summary. This is because summary is a map and maps need a key for each entryset. That means that summary is your map which has a one_summary key.
Is it the SummaryResponse that can't be deserialised?
I guess your attributes should have the same name "totalMR", "totalMA"....
or you should use an annotation JsonProperty(value="totalMR") and so on.
I already have some API and cannot change any parameters and object names into.
One of them is it:
{
"version":"1.0",
"error_code":"0",
"error_message":"OK",
"session_id":"2f0513adszdab61a4748553c62019a",
"expire":"2014-12-13 17:38:13",
"currencyData":{
"rate":"1",
"position":"1",
"ch":"dollar"
},
"data":{
"user_id":129733,
"account_type":0
},
"new":{
"messages_count":0,
"purchases_count":0,
"sales_count":0,
"offers_count":0,
"orders_count":0,
"cart_count":9
}
}
In this responce i have objects "currencyData", "data" and "new".
Right now i have troubles with this names after Deserialization, they are null.
My code for getting this recult is:
ApiResponse<UserData> response = new Gson().fromJson(json, UserData.class);
And names for target objects is:
private CurrencyData currencyData;
private UserData data;
private New newz;
Somebody can tell me how i can Deserialize this objects?
try this
private CurrencyData currencyData;
private UserData data;
#SerializedName("new")
private New newz;