java.lang.NullPointerException while deserializing with gson - json

Hello everyone i have some trouble to deserialize my json with gson, when i try to deserialize into my List i dont catch any errors but whenever i try to display the content of the List i got a java.lang.NullPointerException.
Here is the json:
{
"_id": "577f81286ed8b475f5faf6fb",
"title": "bad (feat. vassy) [radio edit]",
"album": "Listen",
"artist": {
"_id": "577f81140e8784358e32ae2d",
"name": "david guetta"
},
"genre": {
"_id": "577f81140e8784358e32ae2e",
"name": "dance"
},
"duration": "2m50s",
"year": 2014,
"artwork": {
"small": "https://i.scdn.co/image/f59354f8d3f2841e44c1bd7aa0cd55a22843cfc7",
"medium": "https://i.scdn.co/image/9b092f765831793404d46b816d688135ff32735f",
"large": "https://i.scdn.co/image/6e94ab39c917096d876b895dbab0019953d27a96",
"default": "https://i.scdn.co/image/6e94ab39c917096d876b895dbab0019953d27a96"
},
"extraGenres": [],
"extraArtists": []
}
Here is my model:
public class SongDetails {
public String _id;
public String title;
public String album;
public String duration;
public int year;
#SerializedName("artist") Artist artist;
public static class Artist {
public String _id;
public String name;
}
#SerializedName("genre") Genre genre;
public static class Genre {
public String _id;
public String name;
}
#SerializedName("artwork") Artwork artwork;
public static class Artwork {
public String small;
public String medium;
public String large;
#SerializedName("default")
public String defaultX;
}
#SerializedName("votes") public VotesPlayer votes;
public static class VotesPlayer {
public int upVotes;
public int downVotes;
public int standing;
public String by;
}
}
I try to deserialize like this:
Gson gson = new Gson();
Log.d("playdetails to des", toDeserialize);
// toDeserialize = {"_id":"577f81286ed8b475f5faf6fb","title":"bad (feat. vassy) [radio edit]","album":"Listen","artist":{"_id":"577f81140e8784358e32ae2d","name":"david guetta"},"genre":{"_id":"577f81140e8784358e32ae2e","name":"dance"},"duration":"2m50s","year":2014,"artwork":{"small":"https://i.scdn.co/image/f59354f8d3f2841e44c1bd7aa0cd55a22843cfc7","medium":"https://i.scdn.co/image/9b092f765831793404d46b816d688135ff32735f","large":"https://i.scdn.co/image/6e94ab39c917096d876b895dbab0019953d27a96","default":"https://i.scdn.co/image/6e94ab39c917096d876b895dbab0019953d27a96"},"extraGenres":[],"extraArtists":[]}
try {
Response r = gson.fromJson(toDeserialize, Response.class);
Log.d("deser details", r.myPlaylistDetails.size()+"");
} catch (Exception e) {
e.printStackTrace();
}
public class Response {
public List<SongDetails> myPlaylistDetails;
}
I got this error
W/System.err: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at the line of the : "Log.d("deser details", r.myPlaylistDetails.size()+"");"

I have replaced
Response r = gson.fromJson(toDeserialize, Response.class);
by to deserialize my json properly
SongDetails r = gson.fromJson(toDeserialize, SongDetails.class);
then display my details like this:
Log.d("deser details", r.title);

Related

Unity3D - How Can I parse nested duplicate Json

how to parse json via unity3d with duplicate json ,. this is the code that i have ..
[System.Serializable]
public class datagame
{
public string num_id;
public string delay;
public string status;
public string trac;
public string num_id;
public dataIn[] data;
}
[System.Serializable]
public struct dataIn
{
public string ID;
public string Sort;
public string UnitID;
}
datagame dataz;
and this is the json i have.
{
"result": "ok",
"num_id": "19",
"active": "1",
"datagame": {
"id": "3",
"delay": "1200",
"status": "0",
"trac": "NA",
"num_id": "19",
"data": "[\r\n {\r\n \"ID\":\"PowerBtn Spiral\",\r\n \"Sort\":\"1\"\r\n },\r\n {\r\n \"ID\":\"Effect Spiral\",\r\n \"Sort\":\"1\"\r\n },\r\n {\r\n \"ID\":\"Zdata numQ\",\r\n \"Sort\":\"1\",\r\n \"UnitID\":\"c17\"\r\n }\r\n]"
}
}
how can i to remove \r\n and \ in the json with c# code in unity3d
You mean like e.g.
// This is how your top level Json actually looks like
[Serializable]
public class Root
{
public string result;
public string num_id;
public string active;
public Datagame datagame;
}
[Serializable]
public class Datagame
{
public string num_id;
public string delay;
public string status;
public string trac;
public string num_id;
// At this level your data is still simply a string
public string data;
}
// This will be the root for this inner json array
[Serializable]
public class DataArray
{
public dataIn[] values;
}
[Serializable]
public class dataIn
{
public string ID;
public string Sort;
public string UnitID;
}
And then double parse the json like e.g.
// Get the outer class
var root = JsonUtility.FromJson<Root>(json);
// Get the game data instance
var datagame = root.datagame;
// Wrap this inner json array to fit the DataArray structure
var innerJson = "{\"values\":" + datagame.data + "}";
// Now parse this inner json to DataArray
var dataArray = JsonUtility.FromJson<DataArray>(innerJson);
// Finally you have your data items
dataIn[] dataIns = dataArray.values;
I don't really understand your first point but for the second one try something like:
string dataString = "[\r\n {\r\n \"ID\":\"PowerBtn Spiral\",\r\n \"Sort\":\"1\"\r\n },\r\n {\r\n \"ID\":\"Effect Spiral\",\r\n \"Sort\":\"1\"\r\n },\r\n {\r\n \"ID\":\"Zdata numQ\",\r\n \"Sort\":\"1\",\r\n \"UnitID\":\"c17\"\r\n }\r\n]";
string data = Regex.Replace(dataString , #"\\r\\n", "");
string finaldata = Regex.Replace(data, #"\\""", "");

type parameter in the response json: REST

I sent a request JSON through Postmaster and got a response in which includes
a field "type": "subPOJO", which isn't part of either my sub class or super class. How is it been placed in the response, if it is implicitly done then how to exclude it in the response. Thank you!
Response JSON:
{
"type": "subPOJO",
"superid": "XYZ",
"name": "Rest Response",
"number": 1212
}
The Response POJOs:
Super class:
package org.javaprojects.webapp.services;
public class SuperPOJO {
private String superid;
public String getSuperid() {
return superid;
}
public void setSuperid(String superid) {
this.superid = superid;
}
}
Sub Class:
package org.javaprojects.webapp.services;
public class SubPOJO extends SuperPOJO {
private String name;
private int number;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
Check this out This may Help you

Parse a json object with multiple sub-objects inside with GSON

i have an issue with the response of an API that i want to use, i was developing an APP that consumes this API using Retrofit 1.9.0 and GSON 2.3.1.
The Json that i want to parse is like:
{
"user1": {
"id": 1,
"name": "foo",
"address": "bar"
},
"user2":{
"id": 2,
"name": "foo",
"addres":"bar"
},
... it can be any number of users ...
"userN":{
"id": N,
"name": "foo,
"address": "bar"
}
}
So i have an POJO named User:
public class User{
private int id;
private String name;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
I was trying to parse that json with the configuration Map<String, User>:
Callback< <Map<String, User> > callback
But when i run it, i have a GSON error:
gson expecting array but found object
How can i parse the json in a correct way?
PD: i can't change the API response, it's an external API.
Try specifying a concrete type for you callback, like HashMap. Map is an interface.
Callback< <HashMap<String, User> > callback;
Usually you will get casting exception instead of a parsing error, but worth a try.

JsonArray and Gson

The JSON library I'm using is Gson. I'm having difficulty formulating a functioning data type to represent the following JSON string:
{
"latestoffers": [
{
"id": "4qXleunwNMCKi8M0q0CuMa",
"price": "534.99",
"firstrecorded_at": 1377808800,
"lastrecorded_at": 1382862800,
"seller": "Newegg",
"availability": "In stock. [BBX: Buy Box]",
"currency": "USD"
},
{
"id": "4xTIQAPySG68IS0CGyOuyO",
"price": "582.41",
"firstrecorded_at": 1380725000,
"lastrecorded_at": 1382862800,
"seller": "Beach Audio",
"currency": "USD"
},
{
"id": "5nW67R2V4CwmE8cwaWsawe",
"price": "578.04",
"firstrecorded_at": 1379524200,
"lastrecorded_at": 1379998900,
"seller": "Beach Audio",
"currency": "USD"
}
],
"offers_count": 6,
"name": "newegg.com",
"recentoffers_count": 2,
"sku": "N82E16834216463",
"url": "http://www.newegg.com/Product/Product.aspx?Item=N82E16834216463"
}
My data class (so far) is as follows, it's the method getOfferData() that I don't how to complete. I'm also not certain whether JsonArray is the appropriate JSON element to be using?
static class LatestOffers {
Integer offers_count;
String name;
Integer recentoffers_count;
String sku;
String url;
java.util.List<JsonArray> getOfferData() {
List<JsonArray> list = new ArrayList<JsonArray>();
// how do I get parse the 'id', 'price', 'firstrecorded_at' etc. to add them to the ArrayList?
return list;
}
Integer getOffers_count() {
return offers_count;
}
String getName() {
return name;
}
Integer getRecentoffers_count() {
return recentoffers_count;
}
String getSku() {
return sku;
}
String getUrl() {
return url;
}
}
Any assistance, please? Thank you.
EDIT
Turns out I was unnecessarily complicating things, this works as intended:
static class LatestOffers {
List<Offer> latestoffers;
List<Offer> getOffer() {
return latestoffers;
}
}
static class Offer {
private String id;
private String price;
private long firstrecorded_at;
private long lastrecorded_at;
private String seller;
private String availability;
private String currency;
String getId() {
return id;
}
String getPrice() {
return price;
}
long getFirstrecorded_at() {
return firstrecorded_at;
}
long getLastrecorded_at() {
return lastrecorded_at;
}
String getSeller() {
return seller;
}
String getAvailability() {
return availability;
}
String getCurrency() {
return currency;
}
}
Thank you to all who answered, I'm accepting the answer of user2762451 as (s)he was the first to suggest the use of another class for the Offer data.
I'd advise you to make new POJO for object in array.
class Offer {
private String id;
private String price;
private long firstRecordedAt;
private long lastRecordedAt;
private String seller;
private String availability;
private String currency;
}
And your LatestOffers class can have a List<Offer> offers; and the method getOfferData() should return List<Offer>.
Basically, the following:
static class LatestOfferDetail {
private int offersCount;
private String name;
private int recentOffersCount;
private String sku;
private String url;
private List<Offer> latestOffers = new ArrayList<Offer>();
//other getters and setters
public List<Offer> getLatestOffers() {
return latestOffers;
}
}
Also, you seem to be following multiple naming conventions in the same piece of code and JSON. With JAVA, it's advisable to follow CamelCaseNaming. I've updated answer to reflect those.
Also, your getter method for latestOffers has a name different from convention. It's advisable to name it like get{FieldName}. I've updated answer to reflect that.
Create another POJO contain all parameter use in array like below :
public class MyOffer
{
private String id;
private double price;
private long firstrecorded_at;
private long lastrecorded_at;
private String seller;
private String availability;
private String currency;
//your getter and setter methods here.
}
Include List of above pojo in your class LatestOffers :
List<MyOffer> latestoffers = new ArrayList<MyOffer>();
your class LatestOffers look like this
static class LatestOffers
{
Integer offers_count;
String name;
Integer recentoffers_count;
String sku;
String url;
List<MyOffer> latestoffers = new ArrayList<MyOffer>();
//getter and setter method
}
Main Class for Test:
public static void main(String[] args) {
LatestOffers lso = new LatestOffers();
lso.setName("N82E16834216463");
lso.setOffers_count(6);
lso.setRecentoffers_count(2);
lso.setSku("N82E16834216463");
lso.setUrl("http://www.newegg.com/Product/Product.aspx?Item=N82E16834216463");
MyOffer offer = null;
List<MyOffer> list = new ArrayList<MyOffer>();
for(int i=0;i<2;i++){
offer = new MyOffer();
offer.setAvailability("In stock. [BBX: Buy Box]");
offer.setCurrency("USD");
offer.setFirstrecorded_at(1377808800);
offer.setId("4qXleunwNMCKi8M0q0CuMa");
offer.setLastrecorded_at(1382862800);
offer.setPrice(534.99);
offer.setSeller("Newegg");
list.add(offer);
}
lso.setLatestoffers(list);
Gson gson = new Gson();
String json = gson.toJson(lso);
System.out.println(json);
}
Output :
{
"offers_count": 6,
"name": "N82E16834216463",
"recentoffers_count": 2,
"sku": "N82E16834216463",
"url": "http://www.newegg.com/Product/Product.aspx?Item=N82E16834216463",
"latestoffers": [
{
"id": "4qXleunwNMCKi8M0q0CuMa",
"price": 534.99,
"firstrecorded_at": 1377808800,
"lastrecorded_at": 1382862800,
"seller": "Newegg",
"availability": "In stock. [BBX: Buy Box]",
"currency": "USD"
},
{
"id": "4qXleunwNMCKi8M0q0CuMa",
"price": 534.99,
"firstrecorded_at": 1377808800,
"lastrecorded_at": 1382862800,
"seller": "Newegg",
"availability": "In stock. [BBX: Buy Box]",
"currency": "USD"
}
]
}
no need to define getOfferData() method just create list of MyOffer class and set that list into latestoffers list define in your class LatestOffers. It will serialize your list into JsonArray when you convert your POJO into JSON String.

Parsing Json with Gson gives nullfield in object

i got JSON that have object inside
{
"status": "OK",
"info": null,
"data": {
"product": {
"productId": "1",
"productName": "Oreo"
}
}
i parse with
ProductResponse.java
public class ProductResponse {
#SerializedName("status")
public String status;
#SerializedName("info")
public String info;
#SerializedName("data")
public Product data;
}
Product.java
public class Product {
#SerializedName("productId")
public String productId;
#SerializedName("productName")
public String productName;
}
and in reponse i get status = "OK", info = null, and data that is product with nullfields
You've defined ProductResponse#data as a String. In the JSON, it's clearly not a string, it's an object. I know nothing about GSON, but surely that's the problem... Now you've changed the question so that data is defined as Product.
But data isn't a Product, it's an object that has a product property.
It seems like you should have
public class ProductResponseData {
#SerializeName("product")
public Product product;
}
and then change ProductResponse's data to be:
#SerializedName("data")
public ProductResponseData data;