JsonArray and Gson - json

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.

Related

Serialize Feign Json Response to object

I've the following Json response coming from a Feign client:
{
"maxResults": 1,
"total": 5,
"isLast": false,
"values": [
{
"id": 37,
"self": "https://your-domain.atlassian.net/rest/agile/1.0/sprint/23",
"state": "active",
"name": "sprint 1",
"goal": "sprint 1 goal"
}
]
}
The feign client:
#FeignClient(name = "jira")
public interface JiraFeignClient {
#GetMapping("/rest/agile/1.0/board/{boardId}/sprint?state=active&maxResults=1")
ActiveSprintResponse getActiveSprint(#PathVariable String boardId);
}
I'd like to define the ActiveSprintResponse class in order to have the information related to the "values" property (I'm only interested in those) of the json response but I don't understand how can I easily represent it.
I would have no problems for the properties "maxResults", "total" etc... but how can easily unpack "values"? I can assume I will always have only one element in the value array.
I've tried defining it like that but it clearly does not work:
public class ActiveSprintResponse {
private final String id;
private final String self;
private final String name;
private final String goal;
public ActiveSprintResponse(String id, String self, String name, String goal) {
this.id = id;
this.self = self;
this.name = name;
this.goal = goal;
}
}
You need to define a class that represents the root JSON object. You can define a property for the values of type List then:
public class ActiveSprintResponseList {
private List<ActiveSprintResponse> values;
// (Other fields omitted for simplicity)
public void setValues(List<ActiveSprintResponse> values) {
this.values = values;
}
public List<ActiveSprintResponse> getValues() {
return values;
}
}
you then need to declare that class as return type:
#FeignClient(name = "jira")
public interface JiraFeignClient {
#GetMapping("/rest/agile/1.0/board/{boardId}/sprint?state=active&maxResults=1")
ActiveSprintResponseList getActiveSprint(#PathVariable String boardId);
}
and use it on the calling side:
ActiveSprintResponseList response = client.getActiveSprint(..);
List<ActiveSprintResponse> values = response.getValues();
// work with values

java.lang.NullPointerException while deserializing with gson

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);

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.

GSON one to one relationship

I want to know what should be the JSON structure for Gson library to work with one to one relationship (also know as belongsTo).
This is my model
public class Course {
private int id;
private String name;
private Teacher teacher;
//...setters and getters
}
public class Teacher {
private int id;
private String name;
private String lastName;
//...setters and getters
}
until now, my JSON format for filling a Course using gson.fromJSON(string,Course.class) is the following:
{
"id":1,
"name":"Math"
}
how can I also fill a Teacher ?
If your JSON was structured like this, I believe GSON should handle it properly.
{
"id":1,
"name":"Math",
"teacher": {
"id": 2,
"name": "John",
"lastName": "Doe"
}
}

Marshalling java Lists with JAXB / JSON for jqGrid using Jettison or Jackson

I am implementing a generic java POJO wrapper for jqGrid consumption, using JAXB and JSON. This is a CXF service so my marshaller libraries of choice are either Jettison or Jackson:
#XmlRootElement(name = "response")
public class JQGridResponseWrapper<T> {
private PaginatedResults<T> results;
public JQGridResponseWrapper() {
}
public JQGridResponseWrapper(PaginatedResults<T> results) {
this.results = results;
}
#XmlElementWrapper(name = "records")
#XmlElement(name = "record")
public List<T> getRecords() {
return results.getRecords();
}
#XmlElement(name = "pager")
public Pager getPager() {
return results.getPager();
}
}
Here's a sample POJO to be wraped by the generic wrapper:
#XmlRootElement
public class Note {
private Long id;
private String subject;
private String description;
private Project project;
public Note() {}
public Note(Long id, String subject, String description, Project project) {
this.id = id;
this.subject = subject;
this.description = description;
this.project = project;
}
#XmlElement(name="noteId")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
}
When marshaling to XML, everything works fine, all types are correctly mapped, and I get a parent <records> element containing an array of <record> elements. But when marshaling to JSON (the project requirement), the 'record' element is unnamed, which makes jqGrid choke:
{"records":[
{"subject":"subject aaa",
"description":"Description dsifj ofdisjo",
"project":{
"projectCode":"HWIIA",
"description":"project description",
"brand":null,
"projectId":101
},
"noteId":201
},
{"subject":"subject bbb",
"description":"Description odisfj doisjf odsijf",
"project":{
"projectCode":"HWIIA",
"description":"project description",
"brand":null,
"projectId":101
},
"noteId":202
},
{"subject":"subject ccc",
"description":"Description oijgf gfoij jgifif",
"project":{
"projectCode":"HWIIA",
"description":"project description",
"brand":null,
"projectId":101
},
"noteId":203
}
],
"pager"{
"recordsPerPage":10,
"currentPage":1,
"fromRecord":1,
"toRecord":3,
"totalRecords":3,
"totalPages":1}}
I need to get a name for each record in the records array. Is there a simple way to make this work, either with Jettion or Jackson? I searched and searched the web but couldn't find a straighforward solution for my target marshaler libraries. I did see some answers for MOXY, but it is problematic for me to change libraries at this point. Any help greatly appreciated.