Retrofit: Problems handling array or single object - java

I have been following other answers but there is a missing step that i cant find which is resulting in call being successful but the data not being parsed correctly because the first call i make returns a list of objects but only 1 object is returned which is all null
MyModel.java
public class MyModel {
#SerializedName("url")
private String mUrl;
#SerializedName("name")
private String mName;
#SerializedName("description")
private String mDescription;
}
MyModelDeserializer.java
This just checks if its array or object and will simply return the array
public class MyModelTypeAdapter implements JsonDeserializer<ArrayList<MyModel>>{
#Override
public ArrayList<MyModel> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
ArrayList<MyModel> objects = new ArrayList<>();
if(json.isJsonArray()){
for(JsonElement e : json.getAsJsonArray()){
objects.add((MyModel)context.deserialize(e,MyModel.class));
}
}else if(json.isJsonObject()){
objects.add((MyModel)context.deserialize(json,MyModel.class));
}
return objects;
}
}
Some other stuff
Gson gson = new GsonBuilder()
.registerTypeAdapter(new TypeToken<ArrayList<MyModel>>() {}.getType(), new MyModelTypeAdapter())
.create();
restAdapter = new RestAdapter.Builder()
.setEndpoint(BuildConstants.BASE_URL)
.setConverter(new GsonConverter(gson))
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
This is the part which confusing me, what do i put as the return type of the callback
#GET(URLConstants.LIST_URL)
void getData(Callback<ArrayList<MyModel>> callback);
Edit JSON data
{
"places": [
{
"url": "www.google.com",
"name": "Google",
"description": "Search engine"
},
{
"url": "www.Facebook.com",
"name": "Facebook",
"description": "Social Network"
},
{
"url": "www.amazon.com",
"name": "Amazon",
"description": "Shopping"
}
]
}

First create a POJO class to handle json. You can use jsonschema2pojo to create pojo class for your json:
public class MyModel {
#Expose
private List<Place> places = new ArrayList<Place>();
/**
*
* #return
* The places
*/
public List<Place> getPlaces() {
return places;
}
/**
*
* #param places
* The places
*/
public void setPlaces(List<Place> places) {
this.places = places;
}
}
public class Place {
#Expose
private String url;
#Expose
private String name;
#Expose
private String description;
/**
*
* #return
* The url
*/
public String getUrl() {
return url;
}
/**
*
* #param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The description
*/
public String getDescription() {
return description;
}
/**
*
* #param description
* The description
*/
public void setDescription(String description) {
this.description = description;
}
}
Next create a restadapter like this:
public class SimpleRestClient {
private SimpleRestApi simpleRestApi;
public SimpleRestClient() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(Constants.BASE_URL)
.build();
simpleRestApi = restAdapter.create(SimpleRestApi.class);
}
public SimpleRestApi getSimpleRestApi() {
return simpleRestApi;
}
}
Now to create the api interface. Here we are setting our POJO class to handle the json response:
public interface SimpleRestApi {
#GET("Enter URL")
public void getSimpleResponse(Callback<MyModel> handlerCallback);
}
Finally call it as follows:
simpleRestApi = new SimpleRestClient().getSimpleRestApi();
simpleRestApi.getSimpleResponse(new Callback<MyModel>() {
#Override
public void success(MyModel responseHandler, Response response) {
// here you can get your url, name and description.
}
#Override
public void failure(RetrofitError error) {
progress.dismiss();
Log.e("CLASS", "JSON: " + error.getCause());
}
});
References:
jsonschema2pojo
A smart way to use retrofit

Related

Creating list of POJOs when the JSON only has objects

I'm using Pocket API to get a list of bookmarked articles and their URLs, there are hundreds, here is a sample with only 2 articles:
{
"status": 1,
"complete": 1,
"list": {
"734233858": {
"item_id": "734233858",
"resolved_id": "734233858",
"given_url": "https://blog.openshift.com/developing-single-page-web-applications-using-java-8-spark-mongodb-and-angularjs/",
"given_title": "",
"favorite": "0",
"status": "0",
"time_added": "1466459879",
"time_updated": "1466459862",
"time_read": "0",
"time_favorited": "0",
"sort_id": 1,
"resolved_title": "Developing Single Page Web Applications using Java 8, Spark, MongoDB, and AngularJS",
"resolved_url": "https://blog.openshift.com/developing-single-page-web-applications-using-java-8-spark-mongodb-and-angularjs/",
"excerpt": "In this post you will learn how to use a micro framework called Spark to build a RESTful backend. The RESTful backend is consumed by a single page web application using AngularJS and MongoDB for data storage. I’ll also show you how to run Java 8 on OpenShift.",
"is_article": "1",
"is_index": "0",
"has_video": "0",
"has_image": "1",
"word_count": "2727"
},
"1015284226": {
"item_id": "1015284226",
"resolved_id": "1015284226",
"given_url": "https://sparktutorials.github.io/2015/08/04/spark-video-tutorials.html",
"given_title": "",
"favorite": "0",
"status": "0",
"time_added": "1466458750",
"time_updated": "1466458737",
"time_read": "0",
"time_favorited": "0",
"sort_id": 0,
"resolved_title": "Spark Video Tutorials",
"resolved_url": "http://sparktutorials.github.io/2015/08/04/spark-video-tutorials.html",
"excerpt": "Our friends over at learnhowtoprogram.com have been working on a series of Java courses for beginners, all of which feature Spark. This post contains an overview of these courses with direct links to their videos.",
"is_article": "1",
"is_index": "0",
"has_video": "0",
"has_image": "0",
"word_count": "41"
}
},
"error": null,
"search_meta": {
"search_type": "normal"
},
"since": 1509309762
}
As you can see the "list": {} has many items, but it's an array, it contains objects. So when I try to generate the POJOs using http://www.jsonschema2pojo.org I get POJOS named after each item's ID :
package model;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class _1015284226 {
#SerializedName("item_id")
#Expose
private String itemId;
#SerializedName("resolved_id")
#Expose
private String resolvedId;
#SerializedName("given_url")
#Expose
private String givenUrl;
#SerializedName("given_title")
#Expose
private String givenTitle;
#SerializedName("favorite")
#Expose
private String favorite;
#SerializedName("status")
#Expose
private String status;
#SerializedName("time_added")
#Expose
private String timeAdded;
#SerializedName("time_updated")
#Expose
private String timeUpdated;
#SerializedName("time_read")
#Expose
private String timeRead;
#SerializedName("time_favorited")
#Expose
private String timeFavorited;
#SerializedName("sort_id")
#Expose
private Integer sortId;
#SerializedName("resolved_title")
#Expose
private String resolvedTitle;
#SerializedName("resolved_url")
#Expose
private String resolvedUrl;
#SerializedName("excerpt")
#Expose
private String excerpt;
#SerializedName("is_article")
#Expose
private String isArticle;
#SerializedName("is_index")
#Expose
private String isIndex;
#SerializedName("has_video")
#Expose
private String hasVideo;
#SerializedName("has_image")
#Expose
private String hasImage;
#SerializedName("word_count")
#Expose
private String wordCount;
/**
* No args constructor for use in serialization
*
*/
public _1015284226() {
}
/**
*
* #param hasImage
* #param givenUrl
* #param status
* #param timeFavorited
* #param isIndex
* #param excerpt
* #param resolvedId
* #param sortId
* #param givenTitle
* #param timeUpdated
* #param isArticle
* #param wordCount
* #param itemId
* #param favorite
* #param timeAdded
* #param hasVideo
* #param resolvedUrl
* #param resolvedTitle
* #param timeRead
*/
public _1015284226(String itemId, String resolvedId, String givenUrl, String givenTitle, String favorite, String status, String timeAdded, String timeUpdated, String timeRead, String timeFavorited, Integer sortId, String resolvedTitle, String resolvedUrl, String excerpt, String isArticle, String isIndex, String hasVideo, String hasImage, String wordCount) {
super();
this.itemId = itemId;
this.resolvedId = resolvedId;
this.givenUrl = givenUrl;
this.givenTitle = givenTitle;
this.favorite = favorite;
this.status = status;
this.timeAdded = timeAdded;
this.timeUpdated = timeUpdated;
this.timeRead = timeRead;
this.timeFavorited = timeFavorited;
this.sortId = sortId;
this.resolvedTitle = resolvedTitle;
this.resolvedUrl = resolvedUrl;
this.excerpt = excerpt;
this.isArticle = isArticle;
this.isIndex = isIndex;
this.hasVideo = hasVideo;
this.hasImage = hasImage;
this.wordCount = wordCount;
}
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getResolvedId() {
return resolvedId;
}
public void setResolvedId(String resolvedId) {
this.resolvedId = resolvedId;
}
public String getGivenUrl() {
return givenUrl;
}
public void setGivenUrl(String givenUrl) {
this.givenUrl = givenUrl;
}
public String getGivenTitle() {
return givenTitle;
}
public void setGivenTitle(String givenTitle) {
this.givenTitle = givenTitle;
}
public String getFavorite() {
return favorite;
}
public void setFavorite(String favorite) {
this.favorite = favorite;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getTimeAdded() {
return timeAdded;
}
public void setTimeAdded(String timeAdded) {
this.timeAdded = timeAdded;
}
public String getTimeUpdated() {
return timeUpdated;
}
public void setTimeUpdated(String timeUpdated) {
this.timeUpdated = timeUpdated;
}
public String getTimeRead() {
return timeRead;
}
public void setTimeRead(String timeRead) {
this.timeRead = timeRead;
}
public String getTimeFavorited() {
return timeFavorited;
}
public void setTimeFavorited(String timeFavorited) {
this.timeFavorited = timeFavorited;
}
public Integer getSortId() {
return sortId;
}
public void setSortId(Integer sortId) {
this.sortId = sortId;
}
public String getResolvedTitle() {
return resolvedTitle;
}
public void setResolvedTitle(String resolvedTitle) {
this.resolvedTitle = resolvedTitle;
}
public String getResolvedUrl() {
return resolvedUrl;
}
public void setResolvedUrl(String resolvedUrl) {
this.resolvedUrl = resolvedUrl;
}
public String getExcerpt() {
return excerpt;
}
public void setExcerpt(String excerpt) {
this.excerpt = excerpt;
}
public String getIsArticle() {
return isArticle;
}
public void setIsArticle(String isArticle) {
this.isArticle = isArticle;
}
public String getIsIndex() {
return isIndex;
}
public void setIsIndex(String isIndex) {
this.isIndex = isIndex;
}
public String getHasVideo() {
return hasVideo;
}
public void setHasVideo(String hasVideo) {
this.hasVideo = hasVideo;
}
public String getHasImage() {
return hasImage;
}
public void setHasImage(String hasImage) {
this.hasImage = hasImage;
}
public String getWordCount() {
return wordCount;
}
public void setWordCount(String wordCount) {
this.wordCount = wordCount;
}
}
the List POJO which contains the items was created as:
package model;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class List {
#SerializedName("1015284226")
#Expose
private model._1015284226 _1015284226;
/**
* No args constructor for use in serialization
*
*/
public List() {
}
/**
*
* #param _1015284226
*/
public List(model._1015284226 _1015284226) {
super();
this._1015284226 = _1015284226;
}
public model._1015284226 get1015284226() {
return _1015284226;
}
public void set1015284226(model._1015284226 _1015284226) {
this._1015284226 = _1015284226;
}
}
which is obviously giving me issues when I try to parse the JSON
I'm using retrofit 2 .
I'm thinking I should refactor the List POJO so it contains an ArrayList of items, but don't want to fiddle too much with what was automatically generated for me.
You can do it manually like this.
JSONObject jsonObj = new JSONObject(json);
JSONObject lists= jsonObj.getJSONObject("list");
Iterator x = lists.keys();
JSONArray jsonArray = new JSONArray();
while (x.hasNext()){
String key = (String) x.next();
jsonArray.put(lists.get(key));
}
jsonArray is your list.
After that, you may parse JSON to object.

HttpLoggingInterceptor for http request & response logging

I'm using retrofit2 and I need to log all request and response. Request and response works perfectly, All I need is to log those request/response, I tried almost every solution, which I found here, but did not find solution. I don't understand what's wrong is here
this is my code
class Factory {
private final static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static NetworkApi.Factory serverApi;
private static HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
private Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RequestApi.BASE_URL)
.client(httpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
public static NetworkApi getApi() {
if (BuildConfig.DEBUG){
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder()
.addHeader("Content-Type", "application/json");
return chain.proceed(builder.build());
}
});
httpClient.interceptors().add(interceptor);
}
if (serverApi == null){
serverApi = new NetworkApi.Factory();
}
return serverApi.retrofit.create(NetworkApi.class);
}
}
libraries :
compile 'com.google.code.gson:gson:2.7'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
Try to use the OkHttpClient as follows:
private OkHttpClient createDefaultOkHttpClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return new OkHttpClient().newBuilder()
.addInterceptor(interceptor)
.build();
}
Then just set this to your retrofit builder:
Retrofit retrofitAsync = new Retrofit.Builder()
.baseUrl(BASE_URL_APPS)
.client(createDefaultOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(rxAdapter)
.build();
Make API call like this.
ApiFactory.java
public class ApiFactory {
/**
* Base URL for API calls
*/
private static final String BASE_URL = "";
public ApiFactory() {
}
private static Retrofit provideRestAdapter() {
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(BaseApplication.getInstance().getOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
public static <S> S createService(Class<S> serviceClass) {
return provideRestAdapter().create(serviceClass);
}
}
LoginService Interface
public interface LoginService {
/**
* To Post FormUrlEncoded to web service
*
* #return Call Object of Type JsonObject
*/
#FormUrlEncoded
#POST("api/login")
Call<JsonObject> login(#Field("email") String email,
#Field("password") String password,
#Field("devicetype") String devicetype,
#Field("deviceid") String deviceid);
}
Make API call here
private void emailLoginRequest() {
LoginService loginService = ApiFactory.createService(LoginService.class);
Call<JsonObject> call = loginService.login(edtEmail.getText().toString(),edtPassword.getText().toString(),mDeviceType,mDeviceToken);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
hideProgressDialog();
if (response.isSuccessful()) {
LOGD(TAG, "onResponse 0: " + response.body().toString());
LoginResponse loginResponse = new Gson().fromJson(response.body().toString(), LoginResponse.class);
System.out.println("+++ get message >> " + loginResponse.getMessage());
int status = loginResponse.getStatus();
}else {
LOGD(TAG, "response fail 0: " + response.body());
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
hideProgressDialog();
LOGD(TAG, "onFailure: " + t.getMessage());
}
});
}
LoginResponse Make changes as per yours.
public class LoginResponse {
#SerializedName("status")
#Expose
private Integer status;
#SerializedName("message")
#Expose
private String message;
#SerializedName("data")
#Expose
private Data data;
/**
* No args constructor for use in serialization
*
*/
public LoginResponse() {
Sample response model
// {
// "status": 1,
// "data": {
// "user_id": "565464564",
// "email": "email#email.com",
// "fullname": "james",
// "username": "james123",
// "country": "54654654",
// "city": "56546465546",
// "token": "dfgdfgdfg545465465464564"
// },
// "message": "Login successfull"
// }
}
/**
*
* #param message
* #param status
* #param data
*/
public LoginResponse(Integer status, String message, Data data) {
this.status = status;
this.message = message;
this.data = data;
}
/**
*
* #return
* The status
*/
public Integer getStatus() {
return status;
}
/**
*
* #param status
* The status
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
*
* #return
* The message
*/
public String getMessage() {
return message;
}
/**
*
* #param message
* The message
*/
public void setMessage(String message) {
this.message = message;
}
/**
* #return The data
*/
public Data getData() {
return data;
}
/**
* #param data The data
*/
public void setData(Data data) {
this.data = data;
}
public class Data {
#SerializedName("user_id")
#Expose
private String userId;
#SerializedName("email")
#Expose
private String email;
/**
* No args constructor for use in serialization
*/
public Data() {
}
/**
* #param email
* #param userId
*/
public Data(String userId, String email) {
this.userId = userId;
this.email = email;
}
/**
* #return The userId
*/
public String getUserId() {
return userId;
}
/**
* #param userId The user_id
*/
public void setUserId(String userId) {
this.userId = userId;
}
/**
* #return The email
*/
public String getEmail() {
return email;
}
/**
* #param email The email
*/
public void setEmail(String email) {
this.email = email;
}
}
}
Enjoy!
I it would be better to add interceptors while creating client using Builder as below code. If you notice we add two interceptors
- Network interceptor > addNetworkInterceptor
- Interceptor > addInterceptor
The main difference is network interceptor only works when there is a real request (not loading from caching). Interceptor log data on both cases loading from network or cache.
Also make sure you are imorting the correct BuildConfig (sometimes autocompletion import it from one of your libraries, then it will be always false)
`OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Logger networkLayerLogger = new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
LogUtils.d("NetworkLayer", message);
}
};
HttpLoggingInterceptor.Logger appLayerLogger = new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
LogUtils.d("ApplicationLayer", message);
}
};
HttpLoggingInterceptor networkLogging = new HttpLoggingInterceptor(networkLayerLogger);
HttpLoggingInterceptor appLogging = new HttpLoggingInterceptor(appLayerLogger);
networkLogging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
appLogging.setLevel(HttpLoggingInterceptor.Level.BODY);
clientBuilder.addNetworkInterceptor(networkLogging);
clientBuilder.addInterceptor(appLogging);
}
`

passing custom object in retrofit2

i am trying to pass a custom object via retrofit2, and my question is that does the server writes my custom object to json automatically or do i have to write a php file for that. In the meanwhile I am posting successfully to the server but unable to write to json.
My aim is to write custom object to server, and write the contents of custom objects to json file.
Here is my Retrofit Api
public interface ApsaraCatalogAPI {
#GET("/apsaratrendz/data/apsara_json_document_v2.json")
Call<List<ApsaraCatalogModel>> getFeed();
#POST("/apsaratrendz/data/apsara_json_orders_document.json")
Call<Void> setOrder(#Body OrderModel orderModel);
}
Here is my calling api function
#Override
public void onClick(View v) {
int total = 0;
if(v.getId()==R.id.fabButtonCart && cartlist.size()!=0)
{
// get details from shared preferences
OrderModel orderModel = new OrderModel();
orderModel.setDate(getDate());
orderModel.setName("ssdfs");
orderModel.setEmail("sdf#gmail.com");
orderModel.setNoofitems(String.valueOf(cartlist.size()));
orderModel.setOrderno("32335");
orderModel.setPhone("9896566444");
for(int i=0; i<cartlist.size();i++){
Productdetail pd = new Productdetail();
pd.getSellingprice(String.valueOf(cartlist.get(i).getSellingPrice()));
pd.getPid(cartlist.get(i).getEANCode());
total += cartlist.get(i).getSellingPrice();
orderModel.getProductdetails().add(pd);
}
//
// now go for insertion using retrofit
requestData(orderModel);
Toast.makeText(getApplicationContext(), "Total Price : Rs."+total+"/-", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "Cart is Empty", Toast.LENGTH_LONG).show();
}
}
And here is my service request for retrofit api, I am passing the newly created POJO OrderModel class.
private void requestData(OrderModel orderModel) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApsaraCatalogAPI service = retrofit.create(ApsaraCatalogAPI.class);
Call<Void> call = service.setOrder(orderModel);
call.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
if(response.isSuccessful()){
Log.d("InApi","Yipppie");
}
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
Log.d("InApi","Kaboom");
}
});
}
My POJO Class is given below:
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class OrderModel {
private String name;
private String email;
private String phone;
private String orderno;
private String date;
private String noofitems;
private List<Productdetail> productdetails = new ArrayList<Productdetail>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The email
*/
public String getEmail() {
return email;
}
/**
*
* #param email
* The email
*/
public void setEmail(String email) {
this.email = email;
}
/**
*
* #return
* The phone
*/
public String getPhone() {
return phone;
}
/**
*
* #param phone
* The phone
*/
public void setPhone(String phone) {
this.phone = phone;
}
/**
*
* #return
* The orderno
*/
public String getOrderno() {
return orderno;
}
/**
*
* #param orderno
* The orderno
*/
public void setOrderno(String orderno) {
this.orderno = orderno;
}
/**
*
* #return
* The date
*/
public String getDate() {
return date;
}
/**
*
* #param date
* The date
*/
public void setDate(String date) {
this.date = date;
}
/**
*
* #return
* The noofitems
*/
public String getNoofitems() {
return noofitems;
}
/**
*
* #param noofitems
* The noofitems
*/
public void setNoofitems(String noofitems) {
this.noofitems = noofitems;
}
/**
*
* #return
* The productdetails
*/
public List<Productdetail> getProductdetails() {
return productdetails;
}
/**
*
* #param productdetails
* The productdetails
*/
public void setProductdetails(List<Productdetail> productdetails) {
this.productdetails = productdetails;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
productdetails class :
import java.util.HashMap;
import java.util.Map;
public class Productdetail {
private String pid;
private String sellingprice;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The pid
* #param s
*/
public String getPid(String s) {
return pid;
}
/**
*
* #param pid
* The pid
*/
public void setPid(String pid) {
this.pid = pid;
}
/**
*
* #return
* The sellingprice
* #param s
*/
public String getSellingprice(String s) {
return sellingprice;
}
/**
*
* #param sellingprice
* The sellingprice
*/
public void setSellingprice(String sellingprice) {
this.sellingprice = sellingprice;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Retrofit generates the json based on your POJO and set it on the post payload.
So, in this case:
#POST("/apsaratrendz/data/apsara_json_orders_document.json")
Call<Void> setOrder(#Body OrderModel orderModel);
the body of the post will be a json representation of orderModel.
If you need to change the names of the atributtes generated in the json you can use SerializedName Annotation, its very useful:
public class OrderModel {
#SerializedName("other_name_for_json")
private String name;
Hope it helps.

Having trouble using strings outside of Volley request onResponse

I have a search dialog in my MainActivity that when used sends the user query to a SearchActivity. From there I send a JSON request using volley and then deserialize the JSON using GSON. all of this is working good and I can even print, for an example, the latitude value of my request using:
System.out.println(cam[0].getLat());
However, all of this must be done within the onResponse of the volley request. I'm trying to send some of the values back to my MainActivity which I know how to do already. I just need to know how to store some of the strings so that I can access them outside of onResponse.
Method that sends request and deserializes it:
private void fetchJsonResponse() {
JsonArrayRequest req = new JsonArrayRequest(myUrl, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Gson gson = new Gson();
String nominatimData = response.toString();
NominatimModel[] cam = gson.fromJson(nominatimData, NominatimModel[].class);
// i'd like to using cam[0].getLat(); outside of this method
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
mRequestQueue.add(req);
}
NominatimModel.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class NominatimModel {
#SerializedName("place_id")
#Expose
private String placeId;
#Expose
private String licence;
#SerializedName("osm_type")
#Expose
private String osmType;
#SerializedName("osm_id")
#Expose
private String osmId;
#Expose
private List<String> boundingbox = new ArrayList<String>();
#Expose
private String lat;
#Expose
private String lon;
#SerializedName("display_name")
#Expose
private String displayName;
#SerializedName("class")
#Expose
private String _class;
#Expose
private String type;
#Expose
private Double importance;
#Expose
private String icon;
/**
* #return The placeId
*/
public String getPlaceId() {
return placeId;
}
/**
* #param placeId The place_id
*/
public void setPlaceId(String placeId) {
this.placeId = placeId;
}
/**
* #return The licence
*/
public String getLicence() {
return licence;
}
/**
* #param licence The licence
*/
public void setLicence(String licence) {
this.licence = licence;
}
/**
* #return The osmType
*/
public String getOsmType() {
return osmType;
}
/**
* #param osmType The osm_type
*/
public void setOsmType(String osmType) {
this.osmType = osmType;
}
/**
* #return The osmId
*/
public String getOsmId() {
return osmId;
}
/**
* #param osmId The osm_id
*/
public void setOsmId(String osmId) {
this.osmId = osmId;
}
/**
* #return The boundingbox
*/
public List<String> getBoundingbox() {
return boundingbox;
}
/**
* #param boundingbox The boundingbox
*/
public void setBoundingbox(List<String> boundingbox) {
this.boundingbox = boundingbox;
}
/**
* #return The lat
*/
public String getLat() {
return lat;
}
/**
* #param lat The lat
*/
public void setLat(String lat) {
this.lat = lat;
}
/**
* #return The lon
*/
public String getLon() {
return lon;
}
/**
* #param lon The lon
*/
public void setLon(String lon) {
this.lon = lon;
}
/**
* #return The displayName
*/
public String getDisplayName() {
return displayName;
}
/**
* #param displayName The display_name
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
* #return The _class
*/
public String getClass_() {
return _class;
}
/**
* #param _class The class
*/
public void setClass_(String _class) {
this._class = _class;
}
/**
* #return The type
*/
public String getType() {
return type;
}
/**
* #param type The type
*/
public void setType(String type) {
this.type = type;
}
/**
* #return The importance
*/
public Double getImportance() {
return importance;
}
/**
* #param importance The importance
*/
public void setImportance(Double importance) {
this.importance = importance;
}
/**
* #return The icon
*/
public String getIcon() {
return icon;
}
/**
* #param icon The icon
*/
public void setIcon(String icon) {
this.icon = icon;
}
}
Example JSON:
[{"place_id":"115063146","licence":"Data © OpenStreetMap contributors, ODbL 1.0. http:\/\/www.openstreetmap.org\/copyright","osm_type":"way","osm_id":"258132245","boundingbox":["29.7156836","29.7278762","-95.3520172","-95.3349753"],"lat":"29.7214917","lon":"-95.3440202128152","display_name":"University of Houston, 4800, Calhoun Road, Houston, Harris County, Texas, 77004, United States of America","class":"amenity","type":"university","importance":0.84733963787614,"icon":"http:\/\/nominatim.openstreetmap.org\/images\/mapicons\/education_university.p.20.png"}]
I'm fairly new to java and Android development so if someone can help me out a bit i'd appreciate it and if I left out any information let me know.
Figured I'd answer this question now that time has passed and I've learned a ton about Android, including how to accomplish this. So I had all my models implement Serializable, and then just bundled the response data and passed it to the other activity. I later, got rid of this and was able to accomplish everything I needed within the onResponse.
I'd steer away from using Serializable if you must do what I was trying to accomplish and instead check out the Parcelable interface, it has the advantage of being faster.
Hope this helps to anyone who comes across this question!

Parsing json to pojo, which consist of lists, Using GSON

I've got a problem when I try to parse a json string into my custom class, which consists of a list of another pojo.
the error I get is:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 226
And the class I try to parse is:
package com.example.client.models;
import java.util.List;
public class Catalog {
private List<Artist> list;
public Catalog() { }
/**
* #param list
*/
public Catalog(List<Artist> list) {
super();
this.list = list;
}
/**
* #return the list
*/
public List<Artist> getList() {
return list;
}
/**
* #param list the list to set
*/
public void setList(List<Artist> list) {
this.list = list;
}
}
And the artist class:
package com.example.client.models;
import java.io.File;
import java.util.List;
public class Artist {
private String artistName;
private List<Album> albumList;
private File artistFile;
public Artist() { }
/**
* #param artistName
* #param albumList
* #param artistFile
*/
public Artist(String artistName, List<Album> albumList, File artistFile) {
super();
this.artistName = artistName;
this.albumList = albumList;
this.artistFile = artistFile;
}
/**
* #return the artistName
*/
public String getArtistName() {
return artistName;
}
/**
* #param artistName the artistName to set
*/
public void setArtistName(String artistName) {
this.artistName = artistName;
}
/**
* #return the albumList
*/
public List<Album> getAlbumList() {
return albumList;
}
/**
* #param albumList the albumList to set
*/
public void setAlbumList(List<Album> albumList) {
this.albumList = albumList;
}
/**
* #return the artistFile
*/
public File getArtistFile() {
return artistFile;
}
/**
* #param artistFile the artistFile to set
*/
public void setArtistFile(File artistFile) {
this.artistFile = artistFile;
}
}
The Album class:
package com.example.client.models;
import java.io.File;
import java.util.List;
public class Album {
private String albumName;
private List<Song> songList;
private File albumFile;
public Album() { }
/**
* #param albumName
* #param songList
* #param albumFile
*/
public Album(String albumName, List<Song> songList, File albumFile) {
super();
this.albumName = albumName;
this.songList = songList;
this.albumFile = albumFile;
}
/**
* #return the albumName
*/
public String getAlbumName() {
return albumName;
}
/**
* #param albumName the albumName to set
*/
public void setAlbumName(String albumName) {
this.albumName = albumName;
}
/**
* #return the songList
*/
public List<Song> getSongList() {
return songList;
}
/**
* #param songList the songList to set
*/
public void setSongList(List<Song> songList) {
this.songList = songList;
}
/**
* #return the albumFile
*/
public File getAlbumFile() {
return albumFile;
}
/**
* #param albumFile the albumFile to set
*/
public void setAlbumFile(File albumFile) {
this.albumFile = albumFile;
}
}
and finally the song class:
package com.example.client.models;
import java.io.File;
public class Song {
private String songName;
private File songFile;
public Song() { }
/**
* #param songName
* #param songFile
*/
public Song(String songName, File songFile) {
super();
this.songName = songName;
this.songFile = songFile;
}
/**
* #return the songName
*/
public String getSongName() {
return songName;
}
/**
* #param songName the songName to set
*/
public void setSongName(String songName) {
this.songName = songName;
}
/**
* #return the songFile
*/
public File getSongFile() {
return songFile;
}
/**
* #param songFile the songFile to set
*/
public void setSongFile(File songFile) {
this.songFile = songFile;
}
}
I already have validated the json string, therefore I guess my problem lays in the GSON parsing. I hope you can help me with my problem
It would be nice if you could give an example or a hint of what to do.
Thanks on beforehand! ;)
EDIT
Hey again
I've included a sample of the JSON string i'm using:
{
"list":[
{
"artistName":"tmpArtistName",
"albumList":[
{
"albumName":"tmpAlbumName",
"songList":[
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
},
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
}
],
"albumFile":"/home/pi/tmpAlbumFile"
},
{
"albumName":"tmpAlbumName",
"songList":[
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
},
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
}
],
"albumFile":"/home/pi/tmpAlbumFile"
}
],
"artistFile":"/home/pi/tmpArtistFile"
},
{
"artistName":"tmpArtistName",
"albumList":[
{
"albumName":"tmpAlbumName",
"songList":[
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
},
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
}
],
"albumFile":"/home/pi/tmpAlbumFile"
},
{
"albumName":"tmpAlbumName",
"songList":[
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
},
{
"songName":"tmpSongName",
"songFile":"/home/pi/tmpSongFile"
}
],
"albumFile":"/home/pi/tmpAlbumFile"
}
],
"artistFile":"/home/pi/tmpArtistFile"
}
]
}
The Gson parser is apparently unable to deserialize strings directly into File objects. Instead it expects a matching JSON object (surrounded by { and }) in order to proceed with the unmarshalling. In order to get around this, you can simply register a type adapter to handle the file attributes:
public class FileTypeAdapter extends TypeAdapter<File> {
#Override
public void write(final JsonWriter out, final File value)
throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(value.getAbsolutePath());
}
}
#Override
public File read(final JsonReader in) throws IOException {
if (in.hasNext()) {
final String name = in.nextString();
return name != null ? new File(name) : null;
}
return null;
}
}
To use this, the rest of your code would remain the same, but replace the creation of your Gson parser:
final Gson gson = new Gson();
With this:
final Gson gson = new GsonBuilder().registerTypeAdapter(File.class,
new FileTypeAdapter()).create();
That should fix the issue.
On a side note, the Jackson library can handle these kind of deserializations with no special customization, if you are inclined and able to switch.

Categories