Parse indefinite ammount of variables from JSON - java

I am currently trying to load an indefinite amount of variables from a JSON array, and have no idea how to do this.
My JSON file is as follows:
{"commands": [
{"cmd": "hello", "params": "%u", "output": "hello %s!"},
{"cmd": "ping", "params": "", "output": "pong!"},
{"cmd": "test", "params": "%ul", "output": "test %s.."}
]}
I am using the GSON library from Google.
Would I have to manually parse each command, or is there a way to achieve this with gson.fromJson()?

You can use a wrapper object containing an array or a collection of Command objects as a model for the deserialization process:
Command.java
public class Command{
private String cmd;
private String params;
private String output;
// Getters and setters
}
CommandWrapper.java
public class CommandWrapper{
private List<Command> commands;
// Getters and setters
}
And then in your class you can deserialize the JSON this way:
Gson gson = new Gson();
CommandWrapper wrapper = gson.fromJson(myInputJson, CommandWrapper.class);
And get your commands as a list.

If the number is really indefinite; you might want to look into creating a Java8 stream from your input; as streams can be (theoretically) without an end.
But probably you should simply return a List of some specific class of yours that nicely "wraps" around the JSON data in your file.

Related

How to process an associative array from JSON in Android Java

I am trying to process the JSON output from https://api.exchangeratesapi.io/latest in my Android app, which is returned in this format:
{
"rates": {
"CAD": 1.5613,
"HKD": 8.9041,
...
"KRW": 1374.71,
"MYR": 4.8304
},
"base": "EUR",
"date": "2020-03-09"
}
I would like to use GSON to process this JSON, so I have added a class ExchangeRates to recieve the data:
class ExchangeRates {
private String base;
private String date;
}
These commands load the JSON into my ExchangeRates class:
Gson gson = new Gson();
ExchangeRates mExchangeRates = gson.fromJson(result, ExchangeRates.class);
However, I cannot figure out how to load the associative array of exchange rates into the class in a scalable manner. I know I could add a static list of the currencies, but I want the code to be able to automatically handle additional currencies if they are added at a later date.
It turned out to be very simple, and yes, #ya379, a HashMap was part of the answer. Given a HashMap data type, GSON will translate the associative array part of the JSON directly to a HashMap:
class ExchangeRates {
private String base;
private String date;
private HashMap<String, Double> rates;
}

Map enveloped response into a POJO

I am trying to map the following response:
{
"data": {
"id": "1574083",
"username": "snoopdogg",
"full_name": "Snoop Dogg",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_1574083_75sq_1295469061.jpg",
"bio": "This is my bio",
"website": "http://snoopdogg.com",
"counts": {
"media": 1320,
"follows": 420,
"followed_by": 3410
}
}
into an object where I only want to retrieve the username, full_name, and id fields.
Ex: something like:
public class User{
String id;
String username;
String full_name;
// getters + setters
}
Is there a way of doing this without first having to store the data object into a Map?
Use Jackson API. It should be simple:
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(jsonString, User.class); //jsonString is your actual json string.
You might want to tweak your User class to match the JSON string. E.g. your user class needs to have a 'data' field as List<Data> data; where 'Data' is another POJO. You can add the "id", "userName", etc fields in the 'Data' pojo.
You can either do it by hand via, for example, regexp or utilize any of JSON libraries like Jackson, GSON etc.
With GSON it's pretty simple. Say your json is stored in a String jsonString variable.
Gson gson = new Gson();
YourObject = gson.fromJson(jsonString, YourObject.class);
Although I'm not sure what will happen, since your jsonString doesn't have a key called User. However, this should work if you first extract data from your jsonString and name your POJO Data.

Parse JSON without object name in Java

I am trying to parse this JSON which is coming as the response to a REST API call. Can you please help me parsing it as key value pairs?
The object names are not present. There is nesting as well. There seems to be no new line between records.
The aim is to extract this data and load it into a database.
[
{
"cc_emails":["feedback#xyz.com"],
"fwd_emails":[],
"reply_cc_emails":["feedback#xyz.com"],
"fr_escalated":false,
"spam":false,
"email_config_id":6000038087,
"group_id":6000110481,
"priority":1,
"requester_id":6010410791,
"responder_id":6002817857,
"source":1,
"company_id":null,
"status":2,
"subject":"fare",
"to_emails":["feedback#xyz.com"],
"product_id":null,
"id":45043,
"type":null,
"due_by":"2016-03-12T08:58:02Z",
"fr_due_by":"2016-03-08T08:58:02Z",
"is_escalated":false,
"description":"Dear xyze Team,\r\n\r\nWhy r u increased fair again and againasas0mail.gmail.com</a>.<br>\n",
"custom_fields":
{
"category":null,
"issue":null,
"route_id":null,
"phone_number":null,
"department":null,
"booking_id":null
},
"created_at":"2016-03-07T08:58:02Z",
"updated_at":"2016-03-07T08:58:03Z",
// ...... repeat
}
]
The best way to do this would be to use http://www.jsonschema2pojo.org/
Enter your json there
Change source type to JSON
set the correct class name and package.
The resulting pojo can be directly mapped from the json
If you are using resttemplate to hit the api then you can use getForObject to automatically set the pojo from the output.
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject-java.lang.String-java.lang.Class-java.lang.Object...-
Using gson you can do this quite simply.
Do a class to match the fields in the json something like:
public class Example {
private List<String> cc_emails;
private List<String> fwd_emails;
private List<String> reply_cc_emails;
private Boolean fr_escalated;
private Boolean spam;
private Integer email_config_id;
...
private CustomFields custom_fields;
private String created_at;
private String updated_at;
}
Then you need to do another to map the custom fields
public class CustomFields {
private String category;
...
}
And using json you can parse it like this:
Type type = new TypeToken<Collection<Example>>(){}.getType();
new Gson().fromJson(json,type);
You have to exaplain to Gson it's a list, if it was a single object it would be this:
new Gson().fromJson(json,Example.class);
This is the aproach I usually take, also in the dates java.sql.Timestamp class might also parse it, you would need to try it though.
You can use Gson (https://github.com/google/gson) or Jackson (https://github.com/FasterXML/jackson) and deserialize it to a Map.

Deserialize an array of objects with Gson

I know how to deserialize normal JSON object with "Gson" library but I am facing problem to deserialize an JSON array with several JSON object and arrays. I am trying to get the time in the arrival_time JSON object in this simple below but I don't know how to structure my class to accomplish that. Can someone explain me how to do that?
Simple:
[{"route": 1,
"info": [
{"direction": "Surrey Quays"},
{"stops": [{"stops_name": " Tenison Way"},
{"arrival_time":{
"mon-fri": [ "05:38", "06:07","06:37"],
"sat": ["05:34","06:01","06:31"],
"son": ["06:02","06:34","07:04"]
}
}
]
}
]
}]
You can parse this Json using following structure:
class ArrivalTime {
public List<String> mon_fri;
public List<String> sat;
public List<String> son;
}
class Stop {
public String stop_name;
public ArrivalTime arrival_time;
}
class Info {
public String direction;
public List<Stop> stops;
}
class RouteInfo {
public Integer route;
public List<Info> info;
}
and then use it like this:
Gson gson = new Gson();
RouteInfo[] routes = gson.fromJson(/* your json string*/, RouteInfo[].class);
Arrival times will be available at something like this (it is ugly but I just want you to present the sample structure for this json string):
System.out.println(routes[0].info.get(1).stops.get(1).arrival_time.sat.get(0));
To learn the structure you could use a javascript object or a online builder.
http://www.jsonschema2pojo.org/

"Dotting" in JSON using Gson on Android

I'm trying to parse a JSON feed using Gson in Android. I know the JSON is valid. I suspect that it is because the format is like this:
"Info":[
{
"Id":"",
"Name":"",
"Description":"",
"Date":""
}
In order to parse this I need to "dot" in. Ex: Info.Name
How can I do this in a serialized DTO?
#SerializedName("Name")
public String name;
#SerializedName("Description")
public String desc;
#SerializedName("Date")
public String date;
I tried to put "Info." in front of each serializedName but that didn't work either. I also know my JSON parsing method works properly, because it's used somewhere else with a different DTO. But in that parsing, I don't have to "dotting" issue.
Can anyone help?
EDIT: I have tried everything you guys posted, and nothing works. The error says:
The JsonDeserializer failed to deserialize json object {"Info":[{".......
SECOND EDIT:
I was able to get rid of the error, but now it returns null. Haha, getting pretty damn frustrated right about now!
I am assuming that the actual JSON you are intaking is valid because the example you provided is not. In your JSON example, you have "Info":[ but there is no outer object containing the "Info" property, which is a must. The valid JSON would be:
{
"Info": [
{
"Id":"",
"Name":"",
"Description":"",
"Date":"",
}
]
}
This is a JSON object that has a property "Info" which has a value that is a list of objects. This list of objects contains one object that has the properties "Id", "Name", "Description", and "Date", all of which have empty-string values.
Here is a quick tutorial on how to use GSON to parse a JSON feed such as the above JSON:
You will need a class to represent the items in the list:
public class InfoItem {
public String Id;
public String Name;
public String Description;
public String Date;
public InfoItem() {}
}
And one to represent the list of Items:
public class InfoItemList extends LinkedList<InfoItem> {
public InfoItemList() { super() };
}
This added complexity is because GSON cannot otherwise get the type of a generic collection from the class data.
And one to represent the overall JSON message:
public class InfoMessage {
public InfoItemList Info;
public InfoMessage() {};
}
And then just:
gson.fromJson(jsonString, InfoMessage.getClass());
If just de-serializing a collection:
Type listType = new TypeToken<List<InfoItem>>() {}.getType();
gson.fromJson(jsonString2, listType);
The Info object is a list because of the []. You have to use the following code to deserialze it:
EDIT:
public class Info {
// as in your question
public String name;
...
}
public class Data {
#SerializedName("Info")
public List<Info> info;
}
Then just use the data class to deserialize your json.

Categories