How Can Retrofit 2.0 Parse Nested JSON Object

Parse a nested json with retrofit 2.0

Root node of your json is not array, but you declared it as List<responseStatus> at interface getPost. So you need to use responseStatus instead current one. And use gettter to access data

@SerializedName("data")
private ArrayList<retroPost> data;

which is array

How can Retrofit 2.0 parse nested JSON object?

Assuming your complete JSON looks like

{
"title": "Recent Uploads tagged android",
"link": "https://www.flickr.com/photos/tags/android/",
"description": "",
"modified": "2015-10-05T05:30:01Z",
"generator": "https://www.flickr.com/",
"items": [
{
"member1": "memeber value",
"member2": "member value"
},
{
"member1": "memeber value",
"member2": "member value"
}
]
}

So Pojo classes would be

public class MainPojo {
private String title;
private String description;
private String link;
private String generator;
private String modified;
private ArrayList<Items> items;

// Getters setters
}

public class Items {
private String member2;
private String member1;

// Getters setters
}

Note : This is similar solution for your JSON. Members of Items.java can be changed if JSON has other keys.


Update for Pojo as new JSON

public class Items {
private String tags;
private String author;
private String title;
private String description;
private String link;
private String author_id;
private String published;
private Media media;

// Getters and Setters
}

public class Media {
private String m;
// Getters and Setters
}

How to parse nested JSON object with Retrofit/Moshi

I found out the reason why I was not getting any response.
In my UpdateFragment, I'm doing this:

            //Get description and image from API
mBookViewModel.response.observe(viewLifecycleOwner, {
println("Get resp " + it)
})

//Create book object
val updatedBook = BookItem(
args.currentBook.id,
bookName,
bookAuthor,
args.currentBook.desc,
args.currentBook.image,
bookRating,
args.currentBook.dateCreated,
bookFinished
)

//update current book
mBookViewModel.updateBook(updatedBook)

Toast.makeText(requireContext(), "Updated book successfully!", Toast.LENGTH_SHORT)
.show()

//navigate back
findNavController().navigate(R.id.action_updateFragment_to_listFragment)

I am navigating back to another fragment before I can observe any changes from the HTTP response. This causes the observer to stop observing any changes, and thus I can't get a response. I just need to put my code inside the callback, so I can do something with the data I received. Like so:

            //Get description and image from API
mBookViewModel.response.observe(viewLifecycleOwner, {
println("Get resp " + it)


//Create book object
val updatedBook = BookItem(
args.currentBook.id,
bookName,
bookAuthor,
args.currentBook.desc,
args.currentBook.image,
bookRating,
args.currentBook.dateCreated,
bookFinished
)

//update current book
mBookViewModel.updateBook(updatedBook)

Toast.makeText(requireContext(), "Updated book successfully!", Toast.LENGTH_SHORT)
.show()

//navigate back
findNavController().navigate(R.id.action_updateFragment_to_listFragment)
})

Hopefully this helps out anyone who has just started out learning LiveData and using HTTP requests.

Retrofit 2.0 nested json with different subtypes

set your data variable datatype Map<String, Champion> instead of setting it object or List and add below getter method into your model to retrieve List<Champion>

public List<Champion> getChampions(){
if(data != null){
return new ArrayList<Value>(data.values());
}
return null; // you can set return new ArrayList<>(); to avoid null exception
}

Retrofit 2.0 Can't parse Json nested object

Why are you defining two fields with the same name (="name")?
BTW,Your class should be something like this:

public class Repo{
private long id;
private String name;
private String full_name;
private Owner owner;
private Parent parent;

public class Parent{
private String name;
private String full_name;
private Owner owner;
}

public class Owner{
private long id;
private String login;
}
}

how to retrieve nested json object with retrofit?

Two ways:

  1. make contact and location an inner class (same file), but the fields will still not be easily accessed from outside.

  2. you can instead create a method to access the attributes in contacts from Address.

I use http://www.jsonschema2pojo.org/ to auto generate the files below

public class Address {

// create a method here to get first/last name
public String getFirstName(){
return primaryContact==null? "" :
primaryContact.getFirstName();
}
// do the same for which ever inner attributes you like to access.

@SerializedName("name")
@Expose
private String name;
@SerializedName("address")
@Expose
private String address;
@SerializedName("location")
@Expose
private Location location;
@SerializedName("email")
@Expose
private String email;
@SerializedName("primaryContact")
@Expose
private PrimaryContact primaryContact;

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

public Location getLocation() {
return location;
}

public void setLocation(Location location) {
this.location = location;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public PrimaryContact getPrimaryContact() {
return primaryContact;
}

public void setPrimaryContact(PrimaryContact primaryContact) {
this.primaryContact = primaryContact;
}

}
-----------------------------------com.example.Location.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Location {

@SerializedName("lon")
@Expose
private Double lon;
@SerializedName("lat")
@Expose
private Double lat;

public Double getLon() {
return lon;
}

public void setLon(Double lon) {
this.lon = lon;
}

public Double getLat() {
return lat;
}

public void setLat(Double lat) {
this.lat = lat;
}

}
-----------------------------------com.example.PrimaryContact.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class PrimaryContact {

@SerializedName("firstName")
@Expose
private String firstName;
@SerializedName("lastName")
@Expose
private String lastName;
@SerializedName("jobTitle")
@Expose
private String jobTitle;
@SerializedName("email")
@Expose
private String email;
@SerializedName("photo")
@Expose
private String photo;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getJobTitle() {
return jobTitle;
}

public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPhoto() {
return photo;
}

public void setPhoto(String photo) {
this.photo = photo;
}

}

How do I parse nested objects with Retrofit 2?

Your POJO class should be like below.

public class Article {

@SerializedName("source")
@Expose
private Source source;
@SerializedName("author")
@Expose
private String author;
@SerializedName("title")
@Expose
private String title;
@SerializedName("description")
@Expose
private String description;
@SerializedName("url")
@Expose
private String url;
@SerializedName("urlToImage")
@Expose
private String urlToImage;
@SerializedName("publishedAt")
@Expose
private String publishedAt;
// your getter setter methods
}

Your NewsList POJO like below.

public class NewsList {

@SerializedName("status")
@Expose
private String status;
@SerializedName("articles")
@Expose
private List<Article> articles = null;
// getter setter
}

And your source POJO like below.

public class Source {

@SerializedName("id")
@Expose
private String id;
@SerializedName("name")
@Expose
private String name;
// getters setters
}

Parsing nested JSON using RetroFit for Android

Turns out to be quite simple using the advice of @corsair992.

Create a custom deserializer to parse string into Json:

public class UserDeserializer implements JsonDeserializer<UserModel> {
@Override
public UserModel deserialize(JsonElement jsonElement, Type typeOF,
JsonDeserializationContext context)
throws JsonParseException {
String userString = jsonElement.getAsString();
JsonElement userJson = new JsonParser().parse(userString);

return new Gson().fromJson(userJson, UserModel.class);
}
}

then set it as a converter on your rest adapter:

RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new GsonConverter(new GsonBuilder().registerTypeAdapter(UserModel.class, new UserDeserializer()).create()))
.setEndpoint(getString(R.string.url_base))
.build();

That will now convert the string into Json and make it function with the model.



Related Topics



Leave a reply



Submit