HttpLoggingInterceptor for http request & response logging - java

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

Related

Parsing JSON with GSON without knowing the value format

hi guys i have a api like this you can see i have a metaData array and all of the items in the array have a Integer id and a string key but value is not the same in all of them i defined the value in the Object but i have an error this is the error
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 3871 path $[0].meta_data
and this is my POJO class
Main Pojo(Product) class
#SerializedName("meta_data")
#Expose
private MetaDatum metaData;
and this is the MetaDatum Class
public class MetaDatum implements Parcelable {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("key")
#Expose
private String key;
#SerializedName("value")
#Expose
private Object value;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(this.id);
dest.writeString(this.key);
dest.writeParcelable((Parcelable) this.value, flags);
}
public MetaDatum() {
}
protected MetaDatum(Parcel in) {
this.id = (Integer) in.readValue(Integer.class.getClassLoader());
this.key = in.readString();
this.value = in.readParcelable(Object.class.getClassLoader());
}
public static final Parcelable.Creator<MetaDatum> CREATOR = new Parcelable.Creator<MetaDatum>() {
#Override
public MetaDatum createFromParcel(Parcel source) {
return new MetaDatum(source);
}
#Override
public MetaDatum[] newArray(int size) {
return new MetaDatum[size];
}
};
}
make all pojo class for your json data using robopojo puligns or http://www.jsonschema2pojo.org/
after that make retrofit object define base url and other things...
public class ApiClient {
private final static String BASE_URL = "https://goorab.com/wp-json/wc/v2/";
public static ApiClient apiClient;
private Retrofit retrofit = null;
public static ApiClient getInstance() {
if (apiClient == null) {
apiClient = new ApiClient();
}
return apiClient;
}
//private static Retrofit storeRetrofit = null;
public Retrofit getClient() {
return getClient(null);
}
private Retrofit getClient(final Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(60, TimeUnit.SECONDS);
client.writeTimeout(60, TimeUnit.SECONDS);
client.connectTimeout(60, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
}
and make interface for api calling..
public interface ApiInterface {
#GET("products")
Call<ResponseData> getdata(#Query("consumer_key") String key);
}
after that calling into activity or fragment like below.
ApiInterface apiInterface = ApiClient.getInstance().getClient().create(ApiInterface.class);
Call<ResponseData> responseCall = apiInterface.getdata("pass key");
responseCall.enqueue(new Callback<ResponseData>() {
#Override
public void onResponse(Call<ResponseData> call, retrofit2.Response<ResponseData> response) {
if (response.isSuccessful() && response.body() != null && response != null) {
Toast.makeText(getApplicationContext(), "GetData" + response.body().getLanguage(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseData> call, Throwable t) {
Log.d("Errror", t.getMessage());
}
});
and make sure pojo class are all valid.
All Unicode characters may be placed within the quotation marks except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F)
Your meta_data is array instead of object
meta_data": [
{
"id": 3281,
"key": "_vc_post_settings",
"value": {
"vc_grid_id": []
}
]
So use List
private List<MetaDatum> metaData;

Unable to retrieve correct values from rest api (RetroFit)

I am trying to post a request via a JSON body through Retrofit2 in Android.
I am trying to hit api at https://magicspree.com/restaurant/webservice/android/login.
Here is my code.`
Input json body (requests via POST method):
{
"restaurantapikey":"v4Vk2wEkzZfWGxeChavYKLnamLrXaDUJTpiInqeU",
"restaurantusername":"dvar.rddwarka.del",
"restaurantpassword":"password"
}
Restaurant.java(model class):
public class Restaurant {
#SerializedName("restaurantApiKey")
private String restaurantApiKey;
#SerializedName("restaurantUserName")
private String restaurantUserName;
#SerializedName("restaurantPassword")
private String restaurantPassword;
#SerializedName("Status")
#Expose
private String status;
#SerializedName("Text")
#Expose
private String text;
#SerializedName("Restaurant_id")
#Expose
private Integer restaurantId;
public String getRestaurantApiKey() {
return restaurantApiKey;
}
public void setRestaurantApiKey(String restaurantApiKey) {
this.restaurantApiKey = restaurantApiKey;
}
public String getRestaurantUserName() {
return restaurantUserName;
}
public void setRestaurantUserName(String restaurantUserName) {
this.restaurantUserName = restaurantUserName;
}
public String getRestaurantPassword() {
return restaurantPassword;
}
public void setRestaurantPassword(String restaurantPassword) {
this.restaurantPassword = restaurantPassword;
}
public Restaurant(String apiKey, String userName,String password) {
this.restaurantApiKey = apiKey;
this.restaurantUserName = userName;
this.restaurantPassword=password;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Integer getRestaurantId() {
return restaurantId;
}
public void setRestaurantId(Integer restaurantId) {
this.restaurantId = restaurantId;
}
public String toString(){
return "id="+restaurantId+", status="+getStatus()+", text="+getText();
}
}
ApiClient.java:
public class ApiClient {
public static final String BASE_URL =
"https://magicspree.com/restaurant/webservice/android/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
ApiInterface.java:
public interface ApiInterface {
#POST("login")
Call<Restaurant> loginRestaurant(#Body Restaurant restaurant);
}
My onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
Restaurant r=new Restaurant("v4Vk2wEkzZfWGxeChavYKLnamLrXaDUJTpiInqeU","dvar.rddwarka.del","password");
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<Restaurant> call = apiService.loginRestaurant(r);
call.enqueue(new Callback<Restaurant>() {
#Override
public void onResponse(Call<Restaurant> call2, Response<Restaurant> response) {
System.out.println(response.body().toString());
}
#Override
public void onFailure(Call<Restaurant> call, Throwable t) {
}
});
}
Expected output JSON:
{"Status":"Success","Text":"Login Successful","Restaurant_id":27}
The problem is that I am getting the values as Status:Failed, Text:Null, and Restaurant_id:0. I have just started with Retrofit so I do not understand it properly. Please tell me how to retrieve the expected values correctly.
This can be naive but with my eagle eyes :) I see that in Postman your parameter is all in lower case while in your code it is Camel case (restaurantapikey
vs restaurantApiKey )
It might be your backend is implemented with case sensitive parameter.
Change your Restaurant class to use this :
#SerializedName("restaurantapikey")
private String restaurantApiKey;
#SerializedName("restaurantusername")
private String restaurantUserName;
#SerializedName("restaurantpassword")
private String restaurantPassword;

How to parse json data with retrofit on Android

ill try to be specific here. So i have created the most basic possible code just to test it and i am still unable to get the data, please help! Here is my code :
this is json output on my local server :
http://localhost:8080/KokosinjacRestfull/rest/textService/mudriPevci
[{"id":1,"subCategory":"MudriPevci","title":"Mujo i
haso","description":"Krenuli do
Grada","author":"luka","date":"2016-06-13"},{"id":3,"subCategory":"mudriPevci","title":"Perica","description":"Pa
on je napravio Haos","author":"luka","date":"2016-06-13"}]
Text.class :
package kokosinjac.com.digiart.koktest.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Text {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("subCategory")
#Expose
private String subCategory;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("author")
#Expose
private String author;
#SerializedName("date")
#Expose
private String date;
/**
* No args constructor for use in serialization
*
*/
/**
*
* #param id
* #param author
* #param title
* #param subCategory
* #param description
* #param date
*/
/**
*
* #return
* The id
*/
public Integer getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(Integer id) {
this.id = id;
}
/**
*
* #return
* The subCategory
*/
public String getSubCategory() {
return subCategory;
}
/**
*
* #param subCategory
* The subCategory
*/
public void setSubCategory(String subCategory) {
this.subCategory = subCategory;
}
/**
*
* #return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* #param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* #return
* The description
*/
public String getDescription() {
return description;
}
/**
*
* #param description
* The description
*/
public void setDescription(String description) {
this.description = description;
}
/**
*
* #return
* The author
*/
public String getAuthor() {
return author;
}
/**
*
* #param author
* The author
*/
public void setAuthor(String author) {
this.author = author;
}
/**
*
* #return
* The date
*/
public String getDate() {
return date;
}
/**
*
* #param date
* The date
*/
public void setDate(String date) {
this.date = date;
}
}
Api interface.class :
package kokosinjac.com.digiart.koktest.retrofit;
import java.util.ArrayList;
import kokosinjac.com.digiart.koktest.models.Text; import
retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Path;
public interface RetrofitAPInterface {
#GET("rest/textService/{subCategory}")
Call<ArrayList<Text>> getText(#Path("subCategory") String subCat);
}
class that displays data on the phone (you do not need to pay attention on some Strings, just look at the retrofit part,i;ve made it as simple as i can,
subCatData.class:
public static final String BASE_URL ="http://localhost:8080/KokosinjacRestfull/";
HashMap<String,String> dataArr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub_cat_data);
final TextView tView = (TextView) findViewById(R.id.textView);
Intent intent = getIntent();
String urlSecondPartBefore = intent.getStringExtra("passedSubCat");
String urlSecondPartAfter = urlSecondPartBefore.replaceAll("\\s", "");
String urlFirstPart = intent.getStringExtra("passedUrlFirstPart");
String catName = intent.getStringExtra("passedCatName");
String data = null;
// TextView test = (TextView) findViewById(R.id.test);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitAPInterface apiService = retrofit.create(RetrofitAPInterface.class);
Call<ArrayList<Text>> call = apiService.getText("mudriPevci");
call.enqueue(new Callback<ArrayList<Text>>() {
#Override
public void onResponse(Call<ArrayList<Text>> call, Response<ArrayList<Text>> response) {
int statusCode = response.code();
ArrayList<Text> textArray = response.body();
for (Text t : textArray){
tView.setText(t.getDescription());
}
// Log.i("DATA", "onResponse: "+text.getId());
}
#Override
public void onFailure(Call<ArrayList<Text>> call, Throwable t) {
}
});
}
}
I am aware that the whole bunch of data is going to a simple label , but it is for testing purposes. Still i can not retrieve anything and i do not get any errors as well. Help would be much appreciated. Thanks!
I think problem with your URL if you are testing your App with android emulator then try like "http://10.0.2.2:8080/" . but if you are testing with device then you need to pass Your machine IP address like "http://192.143.1.0/". and make sure that your device is connected with your machine on which your database is exits.
To parse JSON data on Android I highly recommend using JSOUP which you can find by clicking here it is simple, straight forward, and user friendly. Very easy to learn. Hope this helps you!
The problem might be in your BASE_URL Change your BASE_URL to
BASE_URL ="http://<your_local_ip_address>/KokosinjacRestfull/";
i hope the below example might help
public void startFetching() {
mApiManager.getFlowerApi().getFlowers(new Callback<String>() {
#Override
public void success(String s, Response response) {
Log.d(TAG, "JSON :: " + s);
try {
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
Flower flower = new Flower.Builder()
.setCategory(object.getString("category"))
.setPrice(object.getDouble("price"))
.setInstructions(object.getString("instructions"))
.setPhoto(object.getString("photo"))
.setName(object.getString("name"))
.setProductId(object.getInt("productId"))
.build();
mListener.onFetchProgress(flower);
}
} catch (JSONException e) {
mListener.onFetchFailed();
}
mListener.onFetchComplete();
}
#Override
public void failure(RetrofitError error) {
Log.d(TAG, "Error :: " + error.getMessage());
mListener.onFetchComplete();
}
});
}
the problem is with your URL Android can't hit your localhost ie http://localhost:8080/KokosinjacRestfull/rest/textService/mudriPevci
up your server in specific IP and the run.The new IP would be like
http://192.168.1.1/KokosinjacRestfull/rest/textService/mudriPevci
use ip address instead of localhost (replace localhost from url and place your computer's ipaddress for ip address open cmd and type ipconfig and replace localhost).

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.

Retrofit: Problems handling array or single object

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

Categories