How to interpret JSON format in android? [duplicate] - java

This question already has answers here:
How to parse JSON in Java
(36 answers)
How do I parse JSON in Android? [duplicate]
(3 answers)
Closed 6 years ago.
I have a url which returns the following, how can I save the data in 3 arrays (Item1Prices[], Item2Prices[], Categories[]) on android? The item prices correspond with the months in the "categories" array. I'm following this tutorial but I need help in modifying the logic in onResponse() to work with mine.
I've seen some examples of this done but I am having trouble recognizing what is what for my case specifically. If someone were to help me get started I would be fine afterwards.
{
"dataset": [
{
"seriesname": "Item1 Price",
"data": [
{
"value": 4.72
},
{
"value": 2.81
},
{
"value": 6.18
},
{
"value": 5.17
},
{
"value": 2.94
},
{
"value": 3.77
},
{
"value": 1.7
},
{
"value": 6.72
},
{
"value": 4.61
}
]
},
{
"seriesname": "Item2 Price",
"data": [
{
"value": 2.49
},
{
"value": 0.72
},
{
"value": 4.06
},
{
"value": 1.74
},
{
"value": 7.23
},
{
"value": 5.83
},
{
"value": 2.59
},
{
"value": 7.54
},
{
"value": 7.02
}
]
}
],
"categories": [
{
"label": "Jan"
},
{
"label": "Feb"
},
{
"label": "Mar"
},
{
"label": "Apr"
},
{
"label": "May"
},
{
"label": "Jun"
},
{
"label": "Jul"
},
{
"label": "Aug"
},
{
"label": "Sept"
}
]
}

I would go with Gson for the parsing.
That way you build annotated POJOs like:
public class MyData{
#Expose #SerializedName("dataset") ArrayList<Series> dataSet;
#Expose #SerializedName("categories") ArrayList<Category> categoryList;
}
and
public class Series {
#Expose #SerializedName("seriesname") String seriesName;
#Expose #SerializedName("data") ArrayList<DataValue> data;
}
and
public class DataValue{
#Expose #SerializedName("data") float dataValue;
}
and
public class Category{
#Expose #SerializedName("label") String label;
}
Then when you need to parse you use:
Gson gson = new GsonBuilder().create();
MyData data = gson.fromJson(jsonString, MyData.class);

Related

Save Nested JSON using Spring data jpa

I want to save data in MYSQL DB by creating Entity class and repository from scratch. I am able to save the normal String Data, Integer Data but struggling to save complex JSON data's
for instance:
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0002",
"type": "donut",
"name": "Raised",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0003",
"type": "donut",
"name": "Old Fashioned",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
How can I store such JSON's in MYSQL Db?
Should I Create Class for every nested element ?
(I would consider to switch to a NoSQL DB instead of MySQL, but okay...)
//1.
create table users_json(
id int auto_increment primary key,
details json);
2.
public interface SomeRepository extends JpaRepository<AnyEntity, Long> {
#Modifying(clearAutomatically = true)
#Query(value = "insert into users_json (details) values (:param) ", nativeQuery = true)
#Transactional
int insertValue(#Param("param") String param);}
3.
anyRepository.insertValue("{ \"page\": \"1\" , \"name\": \"Zafari\", \"os\": \"Mac\", \"spend\": 100, \"resolution\": { \"x\": 1920, \"y\": 1080 } }");
4.
SELECT id, details->'$.name' FROM users_json;
Storing JSON in MySQL is possible. You can use these 3 column types depending upon the column size.
For your Entity class :
#Entity
#Getter
#Setter
public class Test {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(columnDefinition = "LONGTEXT") // can store upto 4GB
private String longText;
#Column(columnDefinition = "MEDIUMTEXT") // can store upto 64MB
private String mediumText;
#Column(columnDefinition = "TEXT") // can store upto 64KB
private String text;
}
For your Controller method :
#PostMapping(value = "/addData")
public void addData(#RequestBody String payload) {
testRepository.addData(payload);
}
For your Repository Class:
#Repository
public interface TestRepository extends JpaRepository<Test,Integer> {
#Modifying
#Transactional
#Query(value = "INSERT INTO test(text,medium_text,long_text) VALUE(?1,?1,?1)" ,nativeQuery = true)
void addData(String payload);
}
In MYSQL it will look like this,
It depends if you want to store your Json as String or do you want to convert it into DTO instances that are mapped to your entities and use repository to save them to DB? If you want to store JSON as a String than It shouldn't be any different from any other String. If you want to store it as Entities than you need to convert your JSON (de-serialize) into your DTOs and then work with them as regular DTOs. It doesn't matter how they where created. I just answered very similar question. Please see here

Consuming a nested JSON array using Spring Boot and RestTemplate

I am attempting to consume an API in my Spring Boot application using an HTTP GET request which returns the below JSON. The issues I'm running into are that there is a JSON array contained inside the "playerentry" level with un-named/unheaded pairs of player and team info. For Spring, one would usually create a java class for each layer of the JSON and use the #JsonProperty() annotation to specify which part of the JSON to generate the Java Objects from. Without names for pairs contained inside the JSON array, and being unsure how to properly setup the java classes for the playerentry array and contained array pairs, I have been unable to use the RestTemplate and RestTemplateBuilder to consume this JSON. Any Help would be greatly appreciated.
{
"rosterplayers": {
"lastUpdatedOn": "2018-02-25 4:24:30 PM",
"playerentry": [
{
"player": {
"ID": "10138",
"LastName": "Abrines",
"FirstName": "Alex"
},
"team": {
"ID": "96",
"City": "Oklahoma City",
"Name": "Thunder",
"Abbreviation": "OKL"
}
},
{
"player": {
"ID": "9466",
"LastName": "Acy",
"FirstName": "Quincy"
},
"team": {
"ID": "84",
"City": "Brooklyn",
"Name": "Nets",
"Abbreviation": "BRO"
}
},
{
"player": {
"ID": "9390",
"LastName": "Adams",
"FirstName": "Steven"
},
"team": {
"ID": "96",
"City": "Oklahoma City",
"Name": "Thunder",
"Abbreviation": "OKL"
}
},
{
"player": {
"ID": "9375",
"LastName": "Afflalo",
"FirstName": "Arron"
},
"team": {
"ID": "103",
"City": "Sacramento",
"Name": "Kings",
"Abbreviation": "SAC"
}
},
{
"player": {
"ID": "9357",
"LastName": "Ajinca",
"FirstName": "Alexis"
},
"team": {
"ID": "110",
"City": "New Orleans",
"Name": "Pelicans",
"Abbreviation": "NOP"
}
},
{
"player": {
"ID": "9272",
"LastName": "Aldrich",
"FirstName": "Cole"
},
"team": {
"ID": "100",
"City": "Minnesota",
"Name": "Timberwolves",
"Abbreviation": "MIN"
}
},
{
"player": {
"ID": "9480",
"LastName": "Aldridge",
"FirstName": "LaMarcus"
},
"team": {
"ID": "106",
"City": "San Antonio",
"Name": "Spurs",
"Abbreviation": "SAS"
}
},
{
"player": {
"ID": "9454",
"LastName": "Alexander",
"FirstName": "Cliff"
},
"team": {
"ID": "95",
"City": "Orlando",
"Name": "Magic",
"Abbreviation": "ORL"
}
},
{
"player": {
"ID": "9299",
"LastName": "Allen",
"FirstName": "Tony"
},
"team": {
"ID": "107",
"City": "Memphis",
"Name": "Grizzlies",
"Abbreviation": "MEM"
}
}
]
}
}
This should work
class Roasterplayers {
String lastUpdatedOn;
List<PlayerEntry> playerentry;
}
class PlayerEntry {
Player player;
Team team;
}
class Player {
#JsonProperty("ID")
String id;
#JsonProperty("LastName")
String lastName;
#JsonProperty("FirstName")
String firstName;
}
class Team {
#JsonProperty("ID")
String id;
#JsonProperty("City")
String city;
#JsonProperty("Name")
String name;
#JsonProperty("Abbreviation")
String abbreviation;
}
Make sure you have Setters and Getters for each field

converting JSON to java object [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What java class structure should I prepare to return such a JSON ?
Corrected JSON (above one is not valid) :
{
"transactionComparisonTotals": [
[
"CurrentFace",
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
],
[
"MarketPrincipal",
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
]
]
}
For this I need set of java classes. O
So one thing I can do is to produce JSON like :
{
"transactionComparisonTotals": [
{
"key": "coupon",
"valueAttributes": [
{
"value": 4.25,
"format": "00.00%",
"color": true,
"sign": true
},
{
"value": 4.26,
"format": "$00.00 %",
"color": true,
"sign": true
},
{
"value": 0.31,
"format": "00.00 bp",
"color": true,
"sign": true
}
]
}
}
But what I actually want is to have "Key" and "valueAttributes" in just one array without property (as shown in my original JSON).
Considering this json file transaction.json: (yours is not valid, so i tried to correct it just to get the idea of serialization and deserilization using gson google API).
{
"transactionComparisonTotals": [
{
"name": "CurrentFace",
"info":
[
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
]
},
{
"name": "MarketPrincipal",
"info":
[
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
]
}
]
}
Create these classes:
Data class:
public class Data{
List<TransactionComparisonTotal> transactionComparisonTotals;
public List<TransactionComparisonTotal> getTransactionComparisonTotals() {
return transactionComparisonTotals;
}
public void setTransactionComparisonTotals(
List<TransactionComparisonTotal> transactionComparisonTotals) {
this.transactionComparisonTotals = transactionComparisonTotals;
}
#Override
public String toString() {
return transactionComparisonTotals.toString();
}
}
TransactionComparisonTotal class:
public class TransactionComparisonTotal{
String name;
List<Info> info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Info> getInfo() {
return info;
}
public void setInfo(List<Info> info) {
this.info = info;
}
#Override
public String toString() {
return "\n"+name+","+info.toString()+"\n";
}
}
Info class:
public class Info{
String value;
String format;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
#Override
public String toString() {
return value+","+format;
}
}
This is a simple example of deserilization using gson google API
public class Transaction {
public static void main(String[] args) throws JsonIOException, JsonSyntaxException, FileNotFoundException {
Gson gson = new Gson();
Data data = gson.fromJson(new BufferedReader(new FileReader(
"transaction.json")), new TypeToken<Data>() {
}.getType());
System.out.println(data);
}
}
Output:
[
CurrentFace,[1000000,$000.00 ptr, 1000,$000.00 ptr, 0,$000.00 ptr]
,
MarketPrincipal,[1000000,$000.00 ptr, 1000,$000.00 ptr, 0,$000.00 ptr]
]

Setting a dynamic date format in Elastic Search

I am new to Elastic Search.
I have a User mapping and associated with the User is a Nested Object extraDataValues. In this object is the id, a string value and another nested object. For example:
"extraDataValues": [
{
"id": 1,
"value": "01/01/2016 00:00:00",
"id": 10,
"label": "Metadata Date",
"displayable": true
},
},
{
"id": 2,
"value": "aaaa",
"id": 11,
"label": "Metadata TextBox",
"displayable": true
},
}
],
As you can see, value field can be a date or a normal string. The problem arises here, I want to be able to sort this value given that it could be either a date or a normal string. Moreover, the date can be in two formats: "dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy". How can I achieve this firstly with Elastic Search (so I can understand the theory) and then Java?
I have tried adding "dynamic_date_formats" : ["dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"]
to no avail.
The mapping for the Users is:
User Mapping Document
{
"User": {
"properties": {
"fullName": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"username": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"email": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"firstName": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"surname": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"id": {
"type": "long"
},
"extraDataValues": {
"type": "nested",
"dynamic_date_formats" : ["dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"],
"properties": {
"extraDataValueObject": {
"properties": {
"id": {
"type": "long"
},
"label": {
"type": "string"
},
"displayable": {
"type": "boolean"
}
}
},
"value": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
}
}
}
}
}
}
You can't do that the way you are trying to do it. dynamic_date_formats are used only for dynamically added date fields, not for date fields that you specify in your mapping (from the documentation).
What I would suggest trying out is this mapping:
"value": {
"type": "string",
"fields": {
"date1": {
"type": "date",
"format": "dd/MM/yyyy HH:mm:ss",
"ignore_malformed": "true"
},
"date2": {
"type": "date",
"format": "dd/MM/yyyy",
"ignore_malformed": "true"
}
}
}
Where you have a field which is string (for the string type part of the value) and for it you define two subfields each with a different date format. It's imperative to have for them "ignore_malformed": "true" in case you really have a string instead of a date coming in.
In this way you can index this:
POST /my_index/user/1
{
"value": "aaa"
}
POST /my_index/user/2
{
"value": "01/01/2016 00:00:00"
}
POST /my_index/user/3
{
"value": "02/02/2016"
}
And you could differentiate between which type of date or string was indexed like this in a query:
"query": {
"filtered": {
"filter": {
"exists": {
"field": "value.date2"
}
}
}
}
If ES was able to index something under value.date2 then you get that document back. The same goes for value.date1, of course.

GSON deserialization of object arrays

I have a class with the following attributes
public class JenkinsServer
{
private String url;
private String mode;
private String nodeName;
private String nodeDescription;
private String description;
private boolean useSecurity;
private boolean quietingDown;
private JenkinsServerView primaryView;
private List< JenkinsJob > jobs;
private List< JenkinsServerView > views;
}
Now I want GSON to deserialize/map a json document to it. It works well, except for my lists - they are empty. The json document looks as follows (snippet):
"jobs": [
{
"name": "AnotherJob",
"url": "https://build.example.com/jenkins/job/AnotherJob/",
"color": "disabled"
},
{
"name": "AnotherJob2",
"url": "https://build.example.com/jenkins/job/Build%20CI%20Build/",
"color": "blue"
},
"views": [
{
"name": "-All Views",
"url": "https://build.example.com/jenkins/view/-All%Views/"
},
{
"name": "Alle",
"url": "https://build.example.com/jenkins/"
},
The mapping works, even for the single instance of
JenkinsServerView primaryView
but not for the Lists. I'm starting the mapping this way:
Gson gson = gsonBuilder.create();
JenkinsServer server = gson.fromJson( reader, JenkinsServer.class );
looks your json data that you are trying to parse is invalid.
In your json jobs and views are arrays and both of them doesn't have the closing brace at the end.
The valid json will be as follows: (Observe the closing braces at the end of the array)
{
"jobs": [
{
"name": "AnotherJob",
"url": "https://build.example.com/jenkins/job/AnotherJob/",
"color": "disabled"
},
{
"name": "AnotherJob2",
"url": "https://build.example.com/jenkins/job/Build%20CI%20Build/",
"color": "blue"
}
],
"views": [
{
"name": "-All Views",
"url": "https://build.example.com/jenkins/view/-All%Views/"
},
{
"name": "Alle",
"url": "https://build.example.com/jenkins/"
}
]
}

Categories