GSON Array to go - android

I'm thinking about it, but I can't print the name and age of the json Crospromotion on the console. I'm using the GSON library, but I'm stuck right now and I don't know how to move forward.
I have my JSON
{
"crospromotion": [
{
"name": "Orus",
"age":14
},
{
"name": "Michelle",
"age":29
},
{
"name": "Jack",
"age":29
}
],
"totalAccessorios": 20,
"totalCaras": 20
}
My JSon controller class:
public class Data {
private Crospromotion crospromotion;
private int totalAccessorios, totalCaras;
public int getTotalAccessorios() {
return totalAccessorios;
}
public int getTotalCaras() {
return totalCaras;
}
}
Class Crospromotion:
public class Crospromotion {
private String nombre;
private int edad;
public String getNombre() {
return nombre;
}
public int getEdad() {
return edad;
}
}
MainActivity:
Gson gson = new Gson();
final Data data = gson.fromJson(myResponse, Data.class);
Log.d("MEN: ", data.getTotalAccessorios());
// I want to print in Log, the fields Crospromotion: name and age. But I don't know how to continue.

The attributes in the json string have different names than in the class Crospromotion. So you can just change the property names of the Crospromotion class like this:
public class Crospromotion {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Also in the json string you have an array of Crospromotion instances, but in the data class you only have one instance. That means you have to change the json string or write the class like this.
import java.util.List;
public class Data {
private List<Crospromotion> crospromotions;
private int totalAccessorios, totalCaras;
public int getTotalAccessorios() {
return totalAccessorios;
}
public int getTotalCaras() {
return totalCaras;
}
public List<Crospromotion> getCrospromotions() {
return crospromotions;
}
}
You also didn't have a getter for the Crospromotion List. Therefore you couldn't access it, because the property was private. With this code you should be able to access the data that you want to access.

It looks like you just forgot to add a getter for your Crospromotion field in your Data class?
public class Data {
private List<Crospromotion> crospromotion;
private int totalAccessorios, totalCaras;
public int getTotalAccessorios() {
return totalAccessorios;
}
public int getTotalCaras() {
return totalCaras;
}
public Crospromotion getCrospromotion() {
return crospromotion;
}
}
...
Log.d("MEN: ", data.getCrospromotion().getAge());
Btw, it looks like the fields in your JSON don't match your Crospromotion class. GSON uses reflection to match json fields to members of a class. You can use #SerializedName() to map JSON field names to member fields if the names differ.
For example:
public class Crospromotion {
#SerializedName("name") private String nombre;
#SerializedName("age") private int edad;
public String getNombre() {
return nombre;
}
public int getEdad() {
return edad;
}
}

Related

How to structure data model for a correct deserialisation?

I am using Retrofit 2.0 to make call to currency conversion API.
I am calling:
https://free.currencyconverterapi.com/api/v6/convert?q=USD_PLN
To receive this response:
{
"query": {
"count": 1
},
"results": {
"USD_PLN": {
"id": "USD_PLN",
"val": 3.763304,
"to": "PLN",
"fr": "USD"
}
}
}
Now I am trying to build data model so that Gson can correctly deserialise this response. I have ResponseWrapper.class
public class ResponseWrapper {
private Query query;
private ConversionPair results;
}
Query.class
public class Query {
private int count;
}
ConversionPair.class
public class ConversionPair {
private String id;
private Currency from;
private Currency to;
private float value;
}
What should I do about USD_PLN object that is in the response body? I want to be able to make different calls with different pairs. I obviously I will not create separate class for every possible pair? What is the proper way of dealing with that?
Best way is to ask API team to change the field and make that generic
{
"query":{
"count":1
},
"results":{
"currency":{ // Currency should be fixed
"id":"USD_PLN",
"val":3.763304,
"to":"PLN",
"fr":"USD"
}
}
}
Use JsonToPojoConverter
public class Example {
#SerializedName("query")
private Query query;
#SerializedName("results")
private Results results;
public Query getQuery() {
return query;
}
public void setQuery(Query query) {
this.query = query;
}
public Results getResults() {
return results;
}
public void setResults(Results results) {
this.results = results;
}
}
public class Query {
#SerializedName("count")
private Integer count;
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}
public class Results {
#SerializedName("USD_PLN")
private USDPLN uSDPLN;
public USDPLN getUSDPLN() {
return uSDPLN;
}
public void setUSDPLN(USDPLN uSDPLN) {
this.uSDPLN = uSDPLN;
}
}
public class USDPLN {
#SerializedName("id")
private String id;
#SerializedName("val")
private Double val;
#SerializedName("to")
private String to;
#SerializedName("fr")
private String fr;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getVal() {
return val;
}
public void setVal(Double val) {
this.val = val;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getFr() {
return fr;
}
public void setFr(String fr) {
this.fr = fr;
}
}
Use JsonElement as results type: JsonElement results; and manually convert it to a Map:
final Type type = new TypeToken<Map<String, ConversionPair>>(){}.getType();
final Map<String, ConversionPair> objects = new Gson().fromJson(results, type);
Now you can loop through objects

How do I create a custom TypeAdapter using Gson for Retrofit 2?

I'm using Retrofit 2 + GsonConverter with a custom model (ResultVO).
I want auto detect and convert the generic type using Gson. I found a solution (TypeToken, TypeAdapter) but I don't know how to create a custom TypeAdapter.
Here is my code:
public class ResultVO<T> {
public Result result;
public Result getResult() {
return result;
}
public class Result {
public String code;
public ArrayList<T> data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public ArrayList<T> getData() {
return data;
}
}
}
Retrofit2 interface method:
#POST("point/getMyPointHistory.json")
Call<ResultVO<MyCustomModelVO>> getMyPointHistory(
#Query("type") String type,
#Query("year") String year,
#Query("month") String month
);

Not receiving data from server using Retrofit 2

I am trying to retrieve Reddit information from a particular subreddit using Retrofit 2. I have followed many tutorials and videos and my code seems to be correct from my perspective but I only manage to have null objects in my model class. I have the permission for internet in the Manifest.
This is a link the JSON I am working with HERE
MainActivity
public class MainActivity extends AppCompatActivity
{
TextView mTextView;
Data mData;
private static final String TAG = "Battlestations";
#Override
protected void onCreate(Bundle savedInstanceState)
{
mTextView = (TextView) findViewById(R.id.test_view);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Call<Data> serviceCall = Service.getDesktopService().desks();
serviceCall.enqueue(new Callback<Data>()
{
#Override
public void onResponse(Call<Data> call, Response<Data> response)
{
Log.d("Reponce","return");
Log.i(TAG, "Response is " + mData.getChildren());
}
#Override
public void onFailure(Call<Data> call, Throwable t)
{
}
});
}
}
Api/Service Class
public class Service
{
private static final String BASE_URL = "https://www.reddit.com/r/";
private static DeskInterface mRetrofit;
public static DeskInterface getDesktopService()
{
if(mRetrofit == null)
{
Retrofit build = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
mRetrofit = build.create(DeskInterface.class);
}
return mRetrofit;
}
public interface DeskInterface
{
#GET("battlestations/hot/.json")
Call<Data> desks();
}
}
Data
public class Data
{
private List<Child> children = null;
public List<Child> getChildren()
{
return children;
}
public void setChildren(List<Child> children)
{
this.children = children;
}
}
Child
public class Child
{
private Data_ data;
public Data_ getData()
{
return data;
}
public void setData(Data_ data)
{
this.data = data;
}
}
Data_
public class Data_
{
private String subreddit;
private Integer score;
private String author;
private String subredditNamePrefixed;
private String url;
private String title;
public String getSubreddit()
{
return subreddit;
}
public void setSubreddit(String subreddit)
{
this.subreddit = subreddit;
}
public Integer getScore()
{
return score;
}
public void setScore(Integer score)
{
this.score = score;
}
public String getAuthor()
{
return author;
}
public void setAuthor(String author)
{
this.author = author;
}
public String getSubredditNamePrefixed()
{
return subredditNamePrefixed;
}
public void setSubredditNamePrefixed(String subredditNamePrefixed)
{
this.subredditNamePrefixed = subredditNamePrefixed;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
}
You need to add mData = response.body() in onResponse() (also check response.isSuccessful() first)
The problem is that your Data does not correspond with Reddit JSON. Your Data class
public class Data {
private List<Child> children = null;
}
does not match with the given json, which is:
{
"kind":"listing",
"data":{
"modhash":"...",
"children":[...],
"after":"...",
"before":"..."
}
}
Retrofit automagically convert from json to java but only if the mapping is correct.
A correct Java class would be:
public class Subreddit {
String kind;
Data data;
}
public class Data{
String modhash;
List<Child> children;
String after;
String before;
}
and then modify desks method interface to
Call<Subreddit> desks();
You would have to go recursively for the entire depth of the JSON to get the right mapping.
But before you get to work, just replace your Retrofit interface:
public interface DeskInterface{
#GET("battlestations/hot/.json")
Call<Data> desks();
}
with:
public interface DeskInterface{
#GET("battlestations/hot/.json")
Call<JsonObject> desks();
}
and it should return something. If is still null, then further investigation is needed. If it returns a valid response(some json text) then copy/paste that subreddit to this website where it converts all the json to a valid Java class

How to use Pojo to get the fields?

Guys recently i switched to Retrofit from volley.
there is a Pojo file which is converted from json.
public class JobModel {
private int status;
private List<JobsBean> jobs;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<JobsBean> getJobs() {
return jobs;
}
public void setJobs(List<JobsBean> jobs) {
this.jobs = jobs;
}
public static class JobsBean {
private String job_city;
public String getJob_city() {
return job_city;
}
}
}
but i don't know how to use this pojo file to extract the job_city from JobsBean class
As you can see there is an JsonArray jobs which is converted to
List<JobsBean>
having JsonObjects and the
JobsBean class
is containing all the job_city name.
How can i retrieve these job_city name in an array.
so that i can use them in my arrayadapter.
Change the POJO structure as follow:
public class JobModel {
private int status;
private List<JobsBean> jobs;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<JobsBean> getJobs() {
return jobs;
}
public void setJobs(List<JobsBean> jobs) {
this.jobs = jobs;
}
}
public class JobsBean {
private String job_city;
public String getJob_city() {
return job_city;
}
public void setJob_city(String job_city) {
this.job_city = job_city;
}
}
The default GsonConverterFactory should be more than enough to handle this nested POJO. And you should be able to get the result like:
JobModel.getJobs().get(index).getJob_city();
Use ArrayAdapter<JobsBean> and it will take a JobsBean list as a parameter for the model data.
You will need to override getView() to read the data from the JobsBean item and put it into the list item view.

Access string from another class

I have different packages in my app like this.
CansTypeObject class looks like this
public class CansTypeObject {
String productId;
String productName;
String productPrice;
String productReturnPrice;
String productImage;
}
Now, I want to access these strings from MainActivity
CansTypeObject object = new CansTypeObject();
But I cant. If I move the CansTypeObject class to the same package as that of MainActivity, I can access them. What is the solution for this?
The default scope is package-private. Use the public modifier on the String declaration
public String productId;
The only reason of this behavior is that you declared yours class Strings as package-protected strings. In Java this means, that this fields will be accessible only for classes in the same package.
There are several solutions for your problem.
The first (and the worst) - declare your fields as public strings, like this:
public String myField;
The second - create getters for your fields and declare your strings as private fields, like this:
private String myField;
public String getMyField() {
return myField;
}
Then, use this getters on your class object.
Hope, it helps.
You can define getter-setter method for the CansTypeObject class as follows for accessing them easily:
public class CansTypeObject {
String productId;
String productName;
String productPrice;
String productReturnPrice;
String productImage;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductPrice() {
return productPrice;
}
public void setProductPrice(String productPrice) {
this.productPrice = productPrice;
}
public String getProductReturnPrice() {
return productReturnPrice;
}
public void setProductReturnPrice(String productReturnPrice) {
this.productReturnPrice = productReturnPrice;
}
public String getProductImage() {
return productImage;
}
public void setProductImage(String productImage) {
this.productImage = productImage;
}
}
for creating getter-setter method you can use shortcut key for
MAC - command + N
Windows - Alt + Insert
Another way is to open the class for which you have to make getter setter and then right click and from the context menu select Generate option

Categories

Resources