How to deserialize this json with Gson? - java

I am going to deserialize this json string with Gson
{
"ads": [
{
"ad": {
"id": 1,
"title": "...",
"publicImage": "...",
"publicUrl": "...",
"adposition": {
"name": "home"
},
"ttl": 30,
"debug": false
}
},
{
"ad": {
"id": 2,
"title": "...",
"publicImage": "...",
"publicUrl": "...",
"adposition": {
"name": "splash"
},
"ttl": 30,
"debug": false
}
},
{
"ad": {
"id": 3,
"title": "...",
"publicImage": "...",
"publicUrl": "...",
"adposition": {
"name": "home"
},
"ttl": 30,
"debug": false
}
}
],
"message": "issue list generated",
"status": "success"
}
and what I have create for classes is (getter setter has been removed) :
public class Ad {
public class AdPosition{
private String mName;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
}
#SerializedName("id")
private int mID;
#SerializedName("title")
private String mTitle;
#SerializedName("publicImage")
private String mPublicImage;
#SerializedName("publicUrl")
private String mPublicUrl;
#SerializedName("ttl")
private int mTtl;
#SerializedName("adposition")
private AdPosition mAdPosition;
}
and
public class AdsListResponse {
#SerializedName("ads")
private List<Ad> mAds;
#SerializedName("message")
private String mMessage;
#SerializedName("status")
private String mStatus;
}
and for converting I use below code
Gson gson = new GsonBuilder().setPrettyPrinting().create();
AdsListResponse ads = gson.fromJson(response, AdsListResponse.class);
for(Ad ad : ads.getAds()){
if(ad.getAdPosition().getName().equalsIgnoreCase("splash")){
System.out.println(ad.getAdPosition().getName());
}
But my list contains objects(Ad) but every field of them is null, for example it has 3 ad but id,title,... are all null, what should I do?
Sorry I copied and paste it wrongly, but still the problem is there, my list of Ad contains Ad but each field of Ad is null

Let's analyze your JSON
{ // an object at the root
"ads": [ // a key value pair, where the value is an array
{ // an object within the array
"ad": { // a key value pair, where the value is an object
// bunch of key value pairs, with int, string, boolean or object values
"id": 1,
"title": "...",
"publicImage": "...",
"publicUrl": "...",
"adposition": {
"name": "home"
},
"ttl": 30,
"debug": false
}
},
Considering that a JSON object maps to a Java POJO, a JSON string maps to a Java String, a JSON array maps to a Java array or Collection, and keys maps to fields, let's analyze your POJO classes
public class AdsListResponse { // root is an object
#SerializedName("ads")
private List<Ad> mAds; // field of type List (Collection) mapping to the array
So you've mapped
{ // an object at the root
"ads": [ // a key value pair, where the value is an array
{
The next token is
"ad": { // a key value pair, where the value is an object
You have no POJO where this exists. You'd need something like
public class AdWrapper {
#SerializedName("ad")
private Ad mAd;
and then change the AdsListResponse to
class AdsListResponse {
#SerializedName("ads")
private List<AdWrapper> mAds;
}
to complete the object tree.

Related

Error parsing JSON (MismatchedInputException)

I'm having problems parsing JSON, this is the error:
out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList<packagename....>` out of START_OBJECT token
And I know why it is happening I just don't know how to fix it. This JSON works:
{
"status_code": "SUCCESS",
"time": {
"date": "Mar 23, 2021 1:14:39 AM"
},
"info": [
{
"person": "2.2",
"role": "TEACHER"
},
{
"person": "2.3",
"role": "TEACHER"
}
]
}
This one does not:
{
"status_code": "SUCCESS",
"time": {
"date": "Mar 23, 2021 3:49:27 AM"
},
"info": {
"id": "1",
"person": [
{
"identifier": "John",
"role": "TEACHER"
},
{
"identifier": "Homer",
"role": "TEACHER"
},
{
"identifier": "Michael",
"role": "TEACHER"
},
{
"identifier": "Sarah",
"role": "TEACHER"
}
]
}
}
The problem seems to be the { character in front of the info field because with [ works. So this is the method I'm using to parse the JSON:
public Mono<PersonResponse> searchById(String id) {
return webClient.get().uri(id).retrieve().bodyToMono(PersonResponse.class);
}
Also tried:
public Mono<PersonResponse[]> searchById(String id) {
return webClient.get().uri(id).retrieve().bodyToMono(PersonResponse[].class);
}
Error right on line: 1, column: 1. Any suggestions of how to implement the method?
EDIT: Added classes.
PersonResponse:
public class PersonResponse implements Serializable{
private static final long serialVersionUID = 7506229887182440471L;
public String status_code;
public Timestamp time;
public List<PersonDetails> info;
public PersonResponse() {}
...getters / setters / toSting
PersonDetails:
public class PersonDetails implements Serializable{
private static final long serialVersionUID = 1294417456651475410L;
private int id;
private List<Person> person;
public PersonDetails(int version) {
super();
this.version = version;
}
...getters / setters / toSting
Person
public class Person implements Serializable{
private static final long serialVersionUID = 3290753964441709903L;
private String identifier;
private String role;
public Person(String identifier, String role) {
super();
this.identifier = identifier;
this.role = role;
}
...getters / setters / toSting
The problem isn't the JSON necessarily, it's that the JSON structure doesn't match your PersonResponse class. There's an info variable in PersonResponse that requires an array of what I assume to be persons, in the second example you're trying to push an object in there, which you can't. You have to either change your JSON, which you don't seem to want in this case, or the class you're trying to parse it to.
You need to restructure the info variable in PersonResponse to match the object you're trying to parse to it.

How can I convert a JSON string of objects into an ArrayList using Gson?

So I have a JSON string of countries like this:
{
"details": [
{
"country_id": "1",
"name": "Afghanistan",
"regions": null
},
{
"country_id": "2",
"name": "Albania",
"regions": null
},
{
"country_id": "3",
"name": "Algeria",
"regions": null
},
... and so on
}
Now I want to have a method that tries to convert this into an ArrayList of countries.
public static ArrayList<GFSCountry> get() {
return new Gson().fromJson(countriesJson, new TypeToken<ArrayList<GFSCountry>>(){}.getType());
}
But I get an
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path
As per request, here is my GFSCountry class:
#SerializedName("country_id")
#Expose
private String countryId;
#SerializedName("name")
#Expose
private String name;
#SerializedName("regions")
#Expose
private Object regions;
public String getCountryId() {
return countryId;
}
public void setCountryId(String countryId) {
this.countryId = countryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getRegions() {
return regions;
}
public void setRegions(Object regions) {
this.regions = regions;
}
I know I should adjust something either from the JSON string or the method. Any help?
Since the list is nested in your JSON you will need a small mapping class that contains the list.
Try
static class GFSCountryList {
public List<GFSCountry> details;
}
public static List<GFSCountry> get() {
return new Gson().fromJson(countriesJson, GFSCountryList.class).details;
}
It seems to me that Gson is expecting your json to be like this
[
{
"country_id": "1",
"name": "Afghanistan",
"regions": null
},
{
"country_id": "2",
"name": "Albania",
"regions": null
},
{
"country_id": "3",
"name": "Algeria",
"regions": null
},
... and so on
]
But it encounters an object (marked by { })
Either you have the possibility to change your json format, or you create a class with a "details" attribut as a list to be compatible with the json's format.

Dynamic Json Parsing Using Gson Android

I have a json as mentioned below.
{
"product": [
{
"classification": "abc",
"ABC": [
{
"classification": "abc",
"name": "abc new product one",
"price": "10775.0000",
},
{
"classification": "abc",
"name": "abc new product two",
"price": "12725.0000",
}
]
},
{
"classification": "def",
"DEF": [
{
"classification": "def",
"name": "def product one",
"price": "728.0000",
},
{
"classification": "def",
"name": "def product two",
"price": "1263.0000",
},
]
}
],
"status": "OK",
"message": "success"
}
In the above json, the key in capital letter is dynamic
(Ex: ABC, DEF)
. I've created pojo class as below:
public class ProductResponse{
private String status;
private String message;
private List<Products>;
Getters And Setters
}
public class Products{
private String classification;
}
I'm struggling to write the next part in Products pojo class, As the keys which are in capitals
(Ex: ABC, DEF)
are dynamic. I am using volley library for getting the data and for parsing I'm using gson library. Please help me out.
You can't have a dynamic name. the reason being is the name in your json needs to be linked to an attribute in your object.
I recommend you to add a "classification" attribute in your json and your model as following :
{
"type": "def",
" results": [
{
"name": "def product one",
"price": "728.0000",
},
{
"name": "def product two",
"price": "1263.0000",
},
]
}
public final class ProductResponse{
private String status;
private String message;
private List<Products> product = new Arraylist<>();
// Getters And Setters
}
public final class Products{
private String type; // type of product // ABC or DEF
private List<Result> results = new Arraylist<>();
// Getters And Setters
}
public final class Result{
private String name;
private String price;
// Getters And Setters
}
Your products class has now a list of results associated to a classification !
Hope it helps !
Your problem is the dynamic key, which I found is not dynamic. As I can see, For each element in the product array, the classification key's value is the next key. Only difference is that they are in capital letters.
{
"classification": "def",
"DEF": [
{
"classification": "def",
"name": "def product one",
"price": "728.0000",
},
{
"classification": "def",
"name": "def product two",
"price": "1263.0000",
},
]
}
As in, here "classification": "def" and the next key is DEF. What I would do here is get the value of classification key, capitalize all the letters in the string and then use it as the key.

Expected BEGIN_OBJECT but was BEGIN_ARRAY for JSON parsing using GSON

Expected BEGIN_OBJECT but was BEGIN_ARRAY for JSON parsing using GSON.
I'm getting error which is occur due to class define for Gson Json implementation
Json Format which need to parse using GSON
{
"StatusCode": 4,
"Data": {
"Data": [
[
{"Value": "19"},{"Value": "19"}],
[
{"Value": "77"},{"Value": "4"}
]
],
"ColumnHeaders": [
{
"Width": "11.0%",
"Title": "Date"
},
{
"Width": "7.6%",
"Title": "Total Clicks"
}
],
"ColumnHeaderGroups": [
{
"ColSpan": "1",
"Title": ""
},
{
"ColSpan": "7",
"Title": "Chats"
},
{
"ColSpan": "3",
"Title": "Times (HH:MM:SS)"
}
],
"ReportHeaders": [
{
"Name": "Title",
"Value": "Chat Summary By Date"
},
{
"Name": "Run Date",
"Value": "05/03/2016 10:52:39 AM"
},
{
"Name": "Time Zone",
"Value": "GMT+00:00"
}
],
"Summary": [
{
"Value": "96"
},
{
"Value": "23"
}
]
},
"Status": "success"
}
Classes for parsing using gson :
static class Page {
String Status;
Data Data;
}
static class Data {
String ReportID;
}
static class Page1 {
String StatusCode;
String Status;
Data1 Data;
}
static class Data1 {
List <Data2> Data;
List<ColumnHeaders> ColumnHeaders;
List<ReportHeaders> ReportHeaders;
List<Summary> Summary;
}
static class Data2{
List<object1> object1;
}
static class object1 {
String Value;
}
static class ColumnHeaders {
String Title;
}
static class Summary {
String Value;
}
static class ReportHeaders {
String Value;
}
Code for parsing json using gson:
need to parse
"Value": "19","Value": "19","Value": "77","Value": "4"
inside Data Array[].
Gson gson = new Gson();
Page1 page = gson.fromJson(json, Page1.class);
String statusString = page.Status;
System.out.println("Status : " + statusString);
System.out.println("StatusCode : " + page.StatusCode);
if ("success".equals(statusString)) {
System.out.println("Inside if");
for (ColumnHeaders item : page.Data.ColumnHeaders)
System.out.print(item.Title + " :");
System.out.println();
for (Summary item1 : page.Data.Summary)
System.out.print(item1.Value + " :");
}
Try changing pojo to this
class Data{
#SerializedName("Data")
#Expose
private List<List<Data2>> Data = new ArrayList<List<Data2>>();
#SerializedName("ColumnHeaders")
#Expose
private List<ColumnHeader> ColumnHeaders = new ArrayList<ColumnHeader>();
#SerializedName("ReportHeaders")
#Expose
private List<ReportHeader> ReportHeaders = new ArrayList<ReportHeader>();
#SerializedName("Summary")
#Expose
private List<Summary> Summary = new ArrayList<Summary>();
//getter setter
}
class Data2{
#SerializedName("Value")
#Expose
private String Value;
//getter setter
}

How to deserialize json with a string-url name-value pair

I have json response in the form
{
"total": 782,
"category": {
"id": 1120,
"name": "Computers & Programming"
},
"experts": [
{
"id": 385816,
"name": "Master Z",
"title": "Mr",
"description": " Expert in C++",
"profile": "http://...com/experts.svc/1.0/385816/..../json?.."
}
}
]
}
I am able to parse everything else in the experts[] array except "profile" whose value "http://...com/experts.svc/1.0/385816/..../json?.." has the following json response
{
"id": 385816,
"name": "Master Z",
"title": "",
"reviewsCount": 15359,
"averageRating": 4.87,
"status": 4,
"fee": 19.99,
"languages": "English",
"category": {
"id": 1120,
"name": "Computers & Programming"
}
}
The models used are as follows
1. main pojo:
public class ExpertObj
{
private String total;
private Category category;
private Experts[] experts;
}
Category pojo:
public class Category
{
private String id;
private String name;
}
3.Experts array pojo:
public class Experts
{
private String id;
private String name;
private String title;
private String description;
private String profile;
}
Am using Retrift 2.
private RestManager mManager;
List<Expert> mExperts = new ArrayList<>();
....
Call<ExpertsObj> call = mManager.getExpertsService().listAllExperts();
call.enqueue(new Callback<ExpertsObj>() {
#Override
public void onResponse(Call<ExpertsObj> call, Response<ExpertsObj> response) {
if (response.isSuccess()) {
ExpertsObj expertsObj = response.body();
mExperts = expertsObj.getExperts();
....}
At a loss how to parse the profile-url name-value pair and display the results in a detail layout in android.
Any help is appreciated.
New in android. Please excuse if anything is not explained properly.

Categories