Convert a JSON String into Java Object - java

i have a String returned by a service, in this JSON format:
String message = {
"Tickets":
[{
"Type": "type1",
"Author": "author1",
"Rows":
[
{
"Price": "100.0",
"Date": "24/06/2016",
"Amount": "10"
},
{
"Type": "Comment",
"Value": "some comment goes here"
}
],
"ID": "165"
}],
"Desk": "desk1",
"User": "user1"
}
I need to parse it and convert into a Java object.
I tried to create a dom like this:
public class TicketWrapper{
private Ticket ticket;
private String desk;
private String user;
}
public class Ticket {
private String type;
private String author;
private List<Row> rows;
private String id;
}
public class Row1{
private float price;
private Date date;
private int amount;
}
public class Row2{
private String type;
private float value;
}
Then I try to parse it with Google Gson, this way:
TicketWrapper ticket = gson.fromJson(message, TicketWrapper.class)
but if I print it System.out.println(gson.toJson(ticket)), it prints:
{"desk" : 0, "user" : 0}
I don't know how to parse that Json into a Java Object, and how to tell him that a row into "Rows" can be of the Row1 type or Row2 type.

I think there is a few issues, such names of properties in lower case and dateformat and mix types of rows. I just changed like this and worked for me:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class CheckTest {
#Test
public void thisTest() {
Gson gson = new GsonBuilder()
.setDateFormat("dd-MM-yyyy")
.setPrettyPrinting()
.create();
String message = "{\"Tickets\":" +
"[{\"Type\":\"type1\"," +
"\"Author\":\"author1\"," +
"\"Rows\":[{\"Price\":\"100.0\"," +
"\"Date\":\"24-06-2016\"," +
"\"Amount\":\"10\"}," +
"{\"Type\":\"Comment\"," +
"\"Value\":\"some comment goes here\"}]," +
"\"ID\":\"165\"}]," +
"\"Desk\":\"desk1\"," +
"\"User\":\"user1\"}";
TicketWrapper ticket = gson.fromJson(message, TicketWrapper.class);
System.out.println(ticket.toString());
}
public class TicketWrapper {
#SerializedName("Tickets")
private List<Ticket> tickets;
#SerializedName("Desk")
private String desk;
#SerializedName("User")
private String user;
public TicketWrapper() {
}
}
public class Ticket {
#SerializedName("Type")
private String type;
#SerializedName("Author")
private String author;
#SerializedName("Rows")
private List<Row> rows;
#SerializedName("ID")
private String id;
public Ticket() {
}
}
public class Row {
#SerializedName("Type")
private String type;
#SerializedName("Value")
private String value;
#SerializedName("Price")
private float price;
#SerializedName("Date")
private Date date;
#SerializedName("Amount")
private int amount;
public Row() {
}
}
}

As others have already mentioned in the comment, you need to make sure the mapping directly reflects the file names. It needs to be 'User' and 'Desk' instead of 'user' and 'desk'. Also, you have a list of tickets, which would map to List Tickets.

Related

What should we do for nested objects in Room? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
If there is a structure like my JSON structure below, how should we create Entity Classes? There are no examples of this. While #embeded was used for inner arrays in the articles written long ago, now a structure like converter is used. Which one should we use? What do these do? How can I create a struct of my type? Please help in Java
All required structures are available here: https://github.com/theoyuncu8/roomdb
JSON Data
{
"MyData": [
{
"food_id": "1",
"food_name": "Food 1",
"food_image": "imageurl",
"food_kcal": "32",
"food_url": "url",
"food_description": "desc",
"carb_percent": "72",
"protein_percent": "23",
"fat_percent": "4",
"units": [
{
"unit": "Unit A",
"amount": "735.00",
"calory": "75.757",
"calcium": "8.580",
"carbohydrt": "63.363",
"cholestrl": "63.0",
"fiber_td": "56.12",
"iron": "13.0474",
"lipid_tot": "13.01",
"potassium": "11.852",
"protein": "717.1925",
"sodium": "112.02",
"vit_a_iu": "110.7692",
"vit_c": "110.744"
},
{
"unit": "Unit C",
"amount": "32.00",
"calory": "23.757",
"calcium": "53.580",
"carbohydrt": "39.363",
"cholestrl": "39.0",
"fiber_td": "93.12",
"iron": "93.0474",
"lipid_tot": "93.01",
"potassium": "9.852",
"protein": "72.1925",
"sodium": "10.0882",
"vit_a_iu": "80.7692",
"vit_c": "80.744"
}
]
},
{
"food_id": "2",
"food_name": "Food 2",
"food_image": "imageurl",
"food_kcal": "50",
"food_url": "url",
"food_description": "desc",
"carb_percent": "25",
"protein_percent": "14",
"fat_percent": "8",
"units": [
{
"unit": "Unit A",
"amount": "25.00",
"calory": "25.757",
"calcium": "55.580",
"carbohydrt": "53.363",
"cholestrl": "53.0",
"fiber_td": "53.12",
"iron": "53.0474",
"lipid_tot": "53.01",
"potassium": "17.852",
"protein": "757.1925",
"sodium": "122.02",
"vit_a_iu": "10.7692",
"vit_c": "10.744"
},
{
"unit": "Unit C",
"amount": "2.00",
"calory": "2.757",
"calcium": "5.580",
"carbohydrt": "3.363",
"cholestrl": "3.0",
"fiber_td": "3.12",
"iron": "3.0474",
"lipid_tot": "3.01",
"potassium": "77.852",
"protein": "77.1925",
"sodium": "12.02",
"vit_a_iu": "0.7692",
"vit_c": "0.744"
},
{
"unit": "Unit G",
"amount": "1.00",
"calory": "2.1",
"calcium": "0.580",
"carbohydrt": "0.363",
"cholestrl": "0.0",
"fiber_td": "0.12",
"iron": "0.0474",
"lipid_tot": "0.01",
"potassium": "5.852",
"protein": "0.1925",
"sodium": "1.02",
"vit_a_iu": "0.7692",
"vit_c": "0.744"
}
]
}
]
}
Entity Class
Foods Class
public class Foods {
#SerializedName("food_id")
#Expose
private String foodId;
#SerializedName("food_name")
#Expose
private String foodName;
#SerializedName("food_image")
#Expose
private String foodImage;
#SerializedName("food_kcal")
#Expose
private String foodKcal;
#SerializedName("food_url")
#Expose
private String foodUrl;
#SerializedName("food_description")
#Expose
private String foodDescription;
#SerializedName("carb_percent")
#Expose
private String carbPercent;
#SerializedName("protein_percent")
#Expose
private String proteinPercent;
#SerializedName("fat_percent")
#Expose
private String fatPercent;
// here
#SerializedName("units")
#Expose
private List<FoodUnitsData> units = null;
// getter setter
}
FoodUnitsData Class
public class FoodUnitsData {
#SerializedName("unit")
#Expose
private String unit;
#SerializedName("amount")
#Expose
private String amount;
#SerializedName("calory")
#Expose
private String calory;
#SerializedName("calcium")
#Expose
private String calcium;
#SerializedName("carbohydrt")
#Expose
private String carbohydrt;
#SerializedName("cholestrl")
#Expose
private String cholestrl;
#SerializedName("fiber_td")
#Expose
private String fiberTd;
#SerializedName("iron")
#Expose
private String iron;
#SerializedName("lipid_tot")
#Expose
private String lipidTot;
#SerializedName("potassium")
#Expose
private String potassium;
#SerializedName("protein")
#Expose
private String protein;
#SerializedName("sodium")
#Expose
private String sodium;
#SerializedName("vit_a_iu")
#Expose
private String vitAIu;
#SerializedName("vit_c")
#Expose
private String vitC;
// getter setter
}
What do these do?
TypeConverters are used to convert a type that room cannot handle to a type that it can (String, primitives, integer types such as Integer, Long, decimal types such as Double, Float).
#Embedded basically says include the member variables of the #Embedded class as columns. e.g. #Embedded FoodUnitsData foodUnitsData;.
Test/Verify the Schema from the Room perspective
With the above class and with the entities defined in the class annotated with #Database (FoodDatabase) it would be a good idea to compile/build the project and fix anything that room complains about (none in this case).
So have FoodDataabse to be :-
#Database(entities = {Foods.class, FoodUnitsDataEntity.class /*<<<<<<<<<< ADDED*/}, version = 1)
public abstract class FoodDatabase extends RoomDatabase {
public abstract DaoAccess daoAccess(); //* do not inlcude this line until the DaoAccess class has been created
}
Note see comment re DaoAccess (i.e. comment out the line)
and then CTRL + F9 and check the build log
Fourth DaoAccess
Obviously FoodUnitsDataEntity rows need to be added, update and deleted. It would also be very convenient if a Foods object could drive adding the FoodUnitsDataEntity rows all in one. This requires a method with a body therefore DaoAccess is changed from an interface to an abstract class to facilitate such a method.
Which one should we use?
You main issue is with the List of FoodUnitsData
Although you could convert the List and use a TypeConverter I would suggest not.
you would probably convert to a JSON string (so you extract from JSON into objects to then store the embedded objects as JSON). You BLOAT the data and also make using that data difficult.
Say for example you wanted to do a search for foods that have 1000 calories or more this would require a pretty complex query or you would load ALL the database and then loop through the foods and then the units.
I would say that #Embedded is the method to use. Along with using #Ignore (the opposite i.e. exclude the member variable from being a column). i.e. you would #Ignore the List in the Foods class.
With #Embedded you can then easily use individual values in queries.
You could then do something like SELECT * FROM the_table_used_for_the_foodunitsdata WHERE calory > 1000 and you would get a List of FoodUnitsData returned. SQLite will do this pretty efficiently.
Working Example
So putting the above into a working example:-
First the Foods class and adding the #Ignore annotation :-
#Entity(tableName = "food_data") // ADDED to make it usable as a Room table
public class Foods {
#SerializedName("food_id")
#Expose
#PrimaryKey // ADDED as MUST have a primary key
#NonNull // ADDED Room does not accept NULLABLE PRIMARY KEY
private String foodId;
#SerializedName("food_name")
#Expose
private String foodName;
#SerializedName("food_image")
#Expose
private String foodImage;
#SerializedName("food_kcal")
#Expose
private String foodKcal;
#SerializedName("food_url")
#Expose
private String foodUrl;
#SerializedName("food_description")
#Expose
private String foodDescription;
#SerializedName("carb_percent")
#Expose
private String carbPercent;
#SerializedName("protein_percent")
#Expose
private String proteinPercent;
#SerializedName("fat_percent")
#Expose
private String fatPercent;
#SerializedName("units")
#Expose
#Ignore // ADDED AS going to be a table
private List<FoodUnitsData> units = null;
#NonNull // ADDED (not reqd)
public String getFoodId() {
return foodId;
}
public void setFoodId(#NonNull /* ADDED #NonNull (not reqd)*/ String foodId) {
this.foodId = foodId;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public String getFoodImage() {
return foodImage;
}
public void setFoodImage(String foodImage) {
this.foodImage = foodImage;
}
public String getFoodKcal() {
return foodKcal;
}
public void setFoodKcal(String foodKcal) {
this.foodKcal = foodKcal;
}
public String getFoodUrl() {
return foodUrl;
}
public void setFoodUrl(String foodUrl) {
this.foodUrl = foodUrl;
}
public String getFoodDescription() {
return foodDescription;
}
public void setFoodDescription(String foodDescription) {
this.foodDescription = foodDescription;
}
public String getCarbPercent() {
return carbPercent;
}
public void setCarbPercent(String carbPercent) {
this.carbPercent = carbPercent;
}
public String getProteinPercent() {
return proteinPercent;
}
public void setProteinPercent(String proteinPercent) {
this.proteinPercent = proteinPercent;
}
public String getFatPercent() {
return fatPercent;
}
public void setFatPercent(String fatPercent) {
this.fatPercent = fatPercent;
}
public List<FoodUnitsData> getUnits() {
return units;
}
public void setUnits(List<FoodUnitsData> units) {
this.units = units;
}
}
The Foods class now has two uses:-
as the class for extracting the JSON (where units will be populated with FoodUnitsData objects accordingly)
as the model for the Room table.
See the comments
Second the FoodUnitsDataEntity class.
This is a new class that will be based upon the FoodUnitsData class but include two important values/columns not catered for by the FoodsUnitsData class, namely:-
a unique identifier that will be the primary key, and
a map/reference for establishing the relationship between a row and it's parent in the Foods table. As this column will be used quite frequently (i.e. it is essential for making the relationship) it makes sense to have an index on the column (speeds up making the relationship (like an index in a book would speed up finding stuff))
as there is a relationship, it is wise to ensure that referential integrity is maintained. That is you don't want orphaned units. As such a Foreign Key constraint is employed (a rule saying that the child must have a parent).
as it will be convenient to build/insert based upon a FoodUnitsData object then a constructor has been added that will create a FoodUnitsDataEnity object from a FoodUnitsData object (plus the all important Foods mapping/referencing/associating value).
So :-
/*
NEW CLASS that:-
Has a Unique ID (Long most efficient) as the primary Key
Has a column to reference/map to the parent FoodUnitsData of the food that owns this
Embeds the FoodUnitsData class
Enforces referential integrity be defining a Foreign Key constraint (optional)
If parent is delete then children are deleted (CASCADE)
If the parent's foodId column is changed then the foodIdMap is updated in the children (CASCADE)
*/
#Entity(
tableName = "food_units",
foreignKeys = {
#ForeignKey(
entity = Foods.class, /* The class (annotated with # Entity) of the owner/parent */
parentColumns = {"foodId"}, /* respective column referenced in the parent (Foods) */
childColumns = {"foodIdMap"}, /* Column in the table that references the parent */
onDelete = CASCADE, /* optional within Foreign key */
onUpdate = CASCADE /* optional with foreign key */
)
}
)
class FoodUnitsDataEntity {
#PrimaryKey
Long foodUnitId = null;
#ColumnInfo(index = true)
String foodIdMap;
#Embedded
FoodUnitsData foodUnitsData;
FoodUnitsDataEntity(){}
FoodUnitsDataEntity(FoodUnitsData fud, String foodId) {
this.foodUnitsData = fud;
this.foodIdMap = foodId;
this.foodUnitId = null;
}
}
Third the FoodUnitsData class
This class is ok as it is. However, for the demo/example constructors were added as per :-
public class FoodUnitsData {
#SerializedName("unit")
#Expose
private String unit;
#SerializedName("amount")
#Expose
private String amount;
#SerializedName("calory")
#Expose
private String calory;
#SerializedName("calcium")
#Expose
private String calcium;
#SerializedName("carbohydrt")
#Expose
private String carbohydrt;
#SerializedName("cholestrl")
#Expose
private String cholestrl;
#SerializedName("fiber_td")
#Expose
private String fiberTd;
#SerializedName("iron")
#Expose
private String iron;
#SerializedName("lipid_tot")
#Expose
private String lipidTot;
#SerializedName("potassium")
#Expose
private String potassium;
#SerializedName("protein")
#Expose
private String protein;
#SerializedName("sodium")
#Expose
private String sodium;
#SerializedName("vit_a_iu")
#Expose
private String vitAIu;
#SerializedName("vit_c")
#Expose
private String vitC;
/* ADDED Constructors */
FoodUnitsData(){}
FoodUnitsData(String unit,
String amount,
String calory,
String calcium,
String cholestrl,
String carbohydrt,
String fiberTd,
String iron,
String lipidTot,
String potassium,
String protein,
String sodium,
String vitAIu,
String vitC
){
this.unit = unit;
this.amount = amount;
this.calory = calory;
this.calcium = calcium;
this.cholestrl = cholestrl;
this.carbohydrt = carbohydrt;
this.fiberTd = fiberTd;
this.iron = iron;
this.lipidTot = lipidTot;
this.potassium = potassium;
this.sodium = sodium;
this.protein = protein;
this.vitAIu = vitAIu;
this.vitC = vitC;
}
/* Finish of ADDED code */
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getCalory() {
return calory;
}
public void setCalory(String calory) {
this.calory = calory;
}
public String getCalcium() {
return calcium;
}
public void setCalcium(String calcium) {
this.calcium = calcium;
}
public String getCarbohydrt() {
return carbohydrt;
}
public void setCarbohydrt(String carbohydrt) {
this.carbohydrt = carbohydrt;
}
public String getCholestrl() {
return cholestrl;
}
public void setCholestrl(String cholestrl) {
this.cholestrl = cholestrl;
}
public String getFiberTd() {
return fiberTd;
}
public void setFiberTd(String fiberTd) {
this.fiberTd = fiberTd;
}
public String getIron() {
return iron;
}
public void setIron(String iron) {
this.iron = iron;
}
public String getLipidTot() {
return lipidTot;
}
public void setLipidTot(String lipidTot) {
this.lipidTot = lipidTot;
}
public String getPotassium() {
return potassium;
}
public void setPotassium(String potassium) {
this.potassium = potassium;
}
public String getProtein() {
return protein;
}
public void setProtein(String protein) {
this.protein = protein;
}
public String getSodium() {
return sodium;
}
public void setSodium(String sodium) {
this.sodium = sodium;
}
public String getVitAIu() {
return vitAIu;
}
public void setVitAIu(String vitAIu) {
this.vitAIu = vitAIu;
}
public String getVitC() {
return vitC;
}
public void setVitC(String vitC) {
this.vitC = vitC;
}
}
Fourth DaoAccess
Obviously inerts/updates/ deletes for the new FoodUnitsDataEntity should be added. However note that existing ones have been changed to not return void but instead long for inserts and int for updates deletes.
inserts return eithr -1 or the rowid (a hidden column that all tables (if using Room) will have that uniquely identifies the inserted row). So if it's -1 then row not inserted (or < 0).
delete and updates return the number of affected (updated/deleted) rows.
It would be beneficial to be able to pass a Food object and insert all the units rows. As this requires a method with a body instead of an interface an abstract class will be used.
So DaoAccess becomes :-
#Dao
public /* CHANGED TO abstract class from interface */ abstract class DaoAccess {
#Query("SELECT * FROM food_data")
abstract List<Foods> getAll();
#Insert(onConflict = OnConflictStrategy.IGNORE)
abstract long insert(Foods task);
#Insert(onConflict = OnConflictStrategy.IGNORE)
abstract long insert(FoodUnitsDataEntity foodUnitsDataEntity);
#Delete
abstract int delete(Foods task);
#Delete
abstract int delete(FoodUnitsDataEntity foodUnitsDataEntity);
#Update
abstract int update(Foods task);
#Update
abstract int update(FoodUnitsDataEntity foodUnitsDataEntity);
#Query("") /* Trick Room to allow the use of #Transaction*/
#Transaction
long insertFoodsWithAllTheFoodUnitsDataEntityChildren(Foods foods) {
long rv = -1;
long fudInsertCount = 0;
if (insert(foods) > 0) {
for(FoodUnitsData fud: foods.getUnits()) {
if (insert(new FoodUnitsDataEntity(fud,foods.getFoodId())) > 0) {
fudInsertCount++;
}
}
if (fudInsertCount != foods.getUnits().size()) {
rv = -(foods.getUnits().size() - fudInsertCount);
} else {
rv = 0;
}
}
return rv;
}
}
Fifth FoodDatabase
Just add the FoodUnitsDataEntity as an entity :-
#Database(entities = {Foods.class, FoodUnitsDataEntity.class /*<<<<<<<<<< ADDED*/}, version = 1)
public abstract class FoodDatabase extends RoomDatabase {
public abstract DaoAccess daoAccess();
}
Sixth testing the above in an Activity MainActivity
This activity will :-
Build a Foods object with some embedded FoodUnitsData.
Save it as a JSON string, extract it from the JSON string (logging
the JSON string)
get an instance of the database.
get an instance of the DaoAccess.
use the insertFoodsWithAllTheFoodUnitsDataEntityChildren method to insert the Foods and the assoctiated/related children.
as per :-
public class MainActivity extends AppCompatActivity {
FoodDatabase fooddb;
DaoAccess foodDao;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Build data to test */
Foods foods = new Foods();
foods.setFoodId("MyFood");
foods.setCarbPercent("10.345");
foods.setFoodDescription("The Food");
foods.setFatPercent("15.234");
foods.setFoodImage("The Food Image");
foods.setFoodKcal("120");
foods.setFoodName("The Food");
foods.setFoodUrl("URL for the Food");
foods.setProteinPercent("16.234");
foods.setUnits(Arrays.asList(
new FoodUnitsData("100","15","1200","11","12","13","14","15","16","17","18","19","20","21"),
new FoodUnitsData("1001","151","12001","11","12","13","14","15","16","17","18","19","20","21"),
new FoodUnitsData("1002","152","12002","11","12","13","14","15","16","17","18","19","20","21")
));
String json = new Gson().toJson(foods);
Log.d("JSONINFO",json);
Foods foodsFromJSON = new Gson().fromJson(json,Foods.class);
fooddb = Room.databaseBuilder(this,FoodDatabase.class,"food.db")
.allowMainThreadQueries()
.build();
foodDao = fooddb.daoAccess();
foodDao.insertFoodsWithAllTheFoodUnitsDataEntityChildren(foodsFromJSON);
}
}
Results after running the App
The log includes :-
D/JSONINFO: {"carb_percent":"10.345","fat_percent":"15.234","food_description":"The Food","food_id":"MyFood","food_image":"The Food Image","food_kcal":"120","food_name":"The Food","food_url":"URL for the Food","protein_percent":"16.234","units":[{"amount":"15","calcium":"11","calory":"1200","carbohydrt":"13","cholestrl":"12","fiber_td":"14","iron":"15","lipid_tot":"16","potassium":"17","protein":"18","sodium":"19","unit":"100","vit_a_iu":"20","vit_c":"21"},{"amount":"151","calcium":"11","calory":"12001","carbohydrt":"13","cholestrl":"12","fiber_td":"14","iron":"15","lipid_tot":"16","potassium":"17","protein":"18","sodium":"19","unit":"1001","vit_a_iu":"20","vit_c":"21"},{"amount":"152","calcium":"11","calory":"12002","carbohydrt":"13","cholestrl":"12","fiber_td":"14","iron":"15","lipid_tot":"16","potassium":"17","protein":"18","sodium":"19","unit":"1002","vit_a_iu":"20","vit_c":"21"}]}
Using App Inspection (Database Inspector) :-
and
Separate them to 2 entities, than create a relation class. This relation class uses FoodListModel as embedded property that has relation to UnitList as List.

How to create Java classes using the reusable json attributes in Jackson?

I need to convert below JSON to Java classes
Here is the JSON
{
"browserName": "chrome",
"env": "test",
"envUrls1": {
"qatesta": {
"fName": "test",
"lName": "test",
"email": "3242342",
"password": "passTestaa"
},
"qatestb": {
"fName": "test",
"lName": "test",
"email": "3242342",
"password": "passTestaa"
},
"qatestc": {
"fName": "test",
"lName": "test",
"email": "3242342",
"password": "passTestaa"
}
}
}
Using above JSON body I able to creates below classes.
1.
public class JsonConfMainObj {
private String browserName;
private String env;
private EnvUrls1 envUrls1;
}
2.
public class EnvUrls1 {
private Qatesta qatesta;
private Qatestb qatestb;
private Qatestc qatestc;
}
3. In each above 'Qatesta', 'Qatestb' and 'Qatestc' Java Classes Contains the below-repeated values
public class Qatestx{
private String fname;
private String lname;
private String email;
private String password;
}
But I need to avoid repeating the above attributes in each class and move them to common Class and map to 'Qatesta', 'Qatestb', and 'Qatestc'.
like below
public class Qatesta{
private Common com;
}
public class Qatestb{
private Common com;
}
public class Qatestc{
private Common com;
}
public class Common{
private String fname;
private String lname;
private String email;
private String password;
}
Is there a way to do this?
You Can use only One class and give the different variable assigned for that class for eg in EnvUrls1 give class Qatest assigned 3 different values
1.
public class JsonConfMainObj {
private String browserName;
private String env;
private EnvUrls1 envUrls1;
}
2.
public class EnvUrls1 {
private Qatest qatesta;
private Qatest qatestb;
private Qatest qatestc;
}
public class Qatest{
private String fname;
private String lname;
private String email;
private String password;
}

How do I consume an array of JSON objects with Spring Boot?

With reference to this guide:
https://spring.io/guides/gs/consuming-rest/
The guide shows how to consume a RESTful web service.
The response from the REST API query results in the following JSON:
{
type: "success",
value: {
id: 10,
quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
}
}
It creates a domain class called Quote.java to contain the data in the response:
package hello;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {
private String type;
private Value value;
public Quote() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
#Override
public String toString() {
return "Quote{" +
"type='" + type + '\'' +
", value=" + value +
'}';
}
}
My questions is how do I represent the following json:
{
"size": 1,
"limit": 25,
"isLastPage": true,
"values": [
{
"user": {
"name": "jcitizen",
"emailAddress": "jane#example.com",
"id": 101,
"displayName": "Jane Citizen",
"active": true,
"slug": "jcitizen",
"type": "NORMAL"
},
"permission": "ADMIN"
}
],
"start": 0
}
The outer objects like size and limit are straightforward but I can't figure out how to represent the values object, which looks like an array of json objects.
This should work.
class Output {
private String size,
private int limit;
private boolean isLastPage,
private List<Value> values;
private int start ;
}
class Value
{
User user,
private String permission;
}
class User {
private String name,
private String emailAddress,
private int id,
private String displayName,
private boolean active,
private String slug,
private String type
}

How to parse a JSON with a property which could be a String or an Object using GSON?

I have a class that should be deserialized accordingly the header request.
If header is on V1 version, ww should output the information field of Product class, like a String. Otherwise it output an Info object.
Is there another solution to do this, instead duplicate the class?
public class Product{
private String name;
private Integer id;
private Info information;
}
public class Info{
private String generalInfo;
private String fullDescription;
private String code;
}
public class Product{
private String name;
private Integer id;
private String information;
}
Above the JSON when use INFO object and when information is a string.
{
"name": "Paul",
"id": "123123,
"information": {
"generalInfo":"Business Product",
"fullDescription":"23",
"code":"9487987289929222-3"
}
}
{
"name": "Paul",
"id": "123123,
"information": "Business Product - 23 - 9487987289929222-3 "
}

Android - Deserialize this JSON to a POJO

This is my JSON:
{
"results": [
{
"user_id": "1",
"item_id": "18630",
"name": "Unnamed Item",
"price": "0",
"description": "",
"created_at": "2014-01-16 15:31:36",
"thumbnail": {
"image50": "http://www.example.com/adsa.jpg",
"image100": "hhttp://www.example.com/adsa.jpg"
},...
Am I doing the deserialization right?
public class ItemListModel {
private String user_id;
private String item_id;
private String name;
private String price;
private String category;
private ArrayList<ThumbnailResponse> thumbnail;
public ItemListModel(){}
// getters
}
public class ThumbnailResponse {
private String image50;
private String image100;
public ThumbnailResponse(){
}
//getters
}
I'm just confused, when do we use ArrayList, Array or List for array or object in the JSON file?
One more thing, do I need to make results as an array too if that's the case?
As you have given
"thumbnail": {
"image50": "http://www.example.com/adsa.jpg",
"image100": "hhttp://www.example.com/adsa.jpg"
}
is not a JsonArray. So you have no need to use ThumbnailResponse as an ArrayList into ItemListModel.
Your Model should be
public class ItemListModel {
private String user_id;
private String item_id;
private String name;
private String price;
private String category;
private ThumbnailResponse thumbnail; // Not array List
public ItemListModel(){}
// getters
}
And
One more thing, do I need to make results as an array too if that's
the case?
Your main data container should be contain ArrayList of ItemListModel. Like below
ArrayList<ItemListModel> results = new ArrayList<ItemListModel>();
[] in json -> array
{} in json -> object or map
in your case
// change
private ArrayList<ThumbnailResponse> thumbnail;
// to
private Map<String,String> thumbnail;
if you want it the way you declared your java object you need to provide a transformer (depends on the framework you are using)
List<ItemListModel > ItemListModel ;
try {
Type listType = new TypeToken<List<ItemListModel >>(){}.getType();
result= (List<ItemListModel >) gson.fromJson(result, listType);
} catch (Exception e) {
Log.e("Parsing exeption", e.getLocalizedMessage(), e);
}
this should work

Categories