Parsing JSON with GSON without knowing the value format - java

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;

Related

How to make parse object to json using retrofit [duplicate]

This question already has answers here:
Why does Gson fromJson throw a JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?
(2 answers)
Closed 5 years ago.
with the next problem, when trying to consume a webservice, then message and presentation;
Expected BEGIN_ARRAY but was BEGIN_OBJECT
I'm not sure how to make a scenario, I've already got data from a webservice, but when it's not a simple array.
I have tried many alternatives, but without success.
response api
{
"_links": {
"self": {
"href": "http://url.com/service?page=1"
},
"first": {
"href": "http://url.com/service"
},
"last": {
"href": "http://url.com/service?page=1"
}
},
"_embedded": {
"data": [
{
"id": 1,
"nome": "teste",
"_links": {
"self": {
"href": "http://url.com/service/1"
}
}
},
{
"id": 2,
"nome": "teste 2",
"_links": {
"self": {
"href": "http://url.com/service/2"
}
}
}
]
},
"page_count": 1,
"page_size": 25,
"total_items": 2,
"page": 1
}
Client
public class ApiClient {
private static final String BASE_URL = "http://url.com/";
private static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Gson gson = new GsonBuilder().setLenient().create();
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
/**
* Get API Service
*
* #return API Service
*/
public static ApiInterface getApiService() {
return getClient().create(ApiInterface.class);
}
}
Interface
/**
* Class ApiInterface
*/
public interface ApiInterface
{
#Headers("Accept: application/json")
#GET("/service")
Call<ArrayList<ServiceData>> getData();
}
Service
public class Service{
#SerializedName("data")
private ArrayList<ServiceData> service = new ArrayList<>();
}
Service Data
public class ServiceData {
#SerializedName("id")
private int id;
public ServiceData(int id, String nome) {
this.id = id;
}
public int getId() {
return id;
}
}
Activity
final Call<ArrayList<ServiceData>> service = apiService.getService();
service.enqueue(new Callback<ArrayList<ServiceData>>() {
#Override
public void onResponse(Call<ArrayList<ServiceData>> call, Response<ArrayList<ServiceData>> response) {
Log.e(TAG, "" + response.body());
}
#Override
public void onFailure(Call<ArrayList<ServiceData>> call, Throwable t) {
Log.e(TAG, "" + t);
}
});
You were in the right path but the response is the whole json and not only the data part you want.
I would create the ResponseApi class:
public class ResponseApi {
#SerializedName("_embedded")
private Service embedded;
}
And change on ApiInterface:
Call<ArrayList<ServiceData>> getData();
To:
Call<ResponseApi> getData();
Also in your activity replace all ArrayList<ServiceData> with ResponseApi.
With only this changes your code should work. And then you'll need to add getters in ResponseApi and Service to access the saved data.
UPDATE adding some getters:
We need the possibility to get the ArrayList of ServiceData of services:
public class Service {
// Your current code
public List<ServiceData> getServices() {
return service;
}
}
And also we could create a getter in ResponseApi to get embedded getEmbedded (I'll add the code as info only) but since we only want the services we could create a getter to the list of services getEmbededServices and use this last method.
public class ResponseApi {
// Your current code
public Service getEmbedded() { // Not used, only shown as info
return embedded;
}
public List<ServiceData> getEmbeddedServices() {
return embedded.getServices();
}
}
This way, when you'll receive a ResponseApi object in the onResponse method you can call its getEmbeddedServices to get the List of ServiceData and then you can loop through them to get the ids:
#Override
public void onResponse(Call<ResponseApi> call, Response<ResponseApi> response) {
Log.d(TAG, "services: " + response.getEmbeddedServices());
// Here you can loop the response.getEmbeddedServices() which is a List of ServiceData and get each of the ids. Ex:
for (ServiceData serviceData : response.getEmbeddedServices()) {
Log.d(TAG, "service Id: " + serviceData.getId());
// Here you have access to the ids and can do whatever you need with them.
}
}
By the way, only as a suggestion, I would rename (with refactor in Android Studio) this service var (in Service class):
private ArrayList<ServiceData> service = new ArrayList<>();
To servicesList:
private ArrayList<ServiceData> servicesList = new ArrayList<>();
And maybe also refactor the Service class to ServicesList class.
It's going to work either you rename them or not but, in my opinion, the code is more readable this way.
Try this
Your Parsing mapping has issues try below Model
ServiceData.java
public class ServiceData {
#SerializedName("_links")
#Expose
private Links links;
#SerializedName("_embedded")
#Expose
private Embedded embedded;
#SerializedName("page_count")
#Expose
private Integer pageCount;
#SerializedName("page_size")
#Expose
private Integer pageSize;
#SerializedName("total_items")
#Expose
private Integer totalItems;
#SerializedName("page")
#Expose
private Integer page;
public Links getLinks() {
return links;
}
public void setLinks(Links links) {
this.links = links;
}
public Embedded getEmbedded() {
return embedded;
}
public void setEmbedded(Embedded embedded) {
this.embedded = embedded;
}
public Integer getPageCount() {
return pageCount;
}
public void setPageCount(Integer pageCount) {
this.pageCount = pageCount;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalItems() {
return totalItems;
}
public void setTotalItems(Integer totalItems) {
this.totalItems = totalItems;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
}
Self_.java
public class Self_ {
#SerializedName("href")
#Expose
private String href;
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
}
Self.java
public class Self {
#SerializedName("href")
#Expose
private String href;
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
}
Links_.java
public class Links_ {
#SerializedName("self")
#Expose
private Self_ self;
public Self_ getSelf() {
return self;
}
public void setSelf(Self_ self) {
this.self = self;
}
}
Links.java
public class Links {
#SerializedName("self")
#Expose
private Self self;
#SerializedName("first")
#Expose
private First first;
#SerializedName("last")
#Expose
private Last last;
public Self getSelf() {
return self;
}
public void setSelf(Self self) {
this.self = self;
}
public First getFirst() {
return first;
}
public void setFirst(First first) {
this.first = first;
}
public Last getLast() {
return last;
}
public void setLast(Last last) {
this.last = last;
}
}
Last.java
public class Last {
#SerializedName("href")
#Expose
private String href;
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
}
First.java
public class First {
#SerializedName("href")
#Expose
private String href;
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
}
Embedded.java
public class Embedded {
#SerializedName("data")
#Expose
private List<Datum> data = null;
public List<Datum> getData() {
return data;
}
public void setData(List<Datum> data) {
this.data = data;
}
}
Datum.java
public class Datum {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("nome")
#Expose
private String nome;
#SerializedName("_links")
#Expose
private Links_ links;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Links_ getLinks() {
return links;
}
public void setLinks(Links_ links) {
this.links = links;
}
}
Try to remove ArrayList from every where and direct use ServiceData
Interface
/**
* Class ApiInterface
*/
public interface ApiInterface
{
#Headers("Accept: application/json")
#GET("/service")
Call<ServiceData> getData();
}
Service Data
public class ServiceData {
#SerializedName("id")
private int id;
public ServiceData(int id, String nome) {
this.id = id;
}
public int getId() {
return id;
}
}
Activity
final Call<ServiceData> service = apiService.getService();
service.enqueue(new Callback<ServiceData>() {
#Override
public void onResponse(Call<ServiceData> call, Response<ServiceData> response) {
Log.e(TAG, "" + response.body());
}
#Override
public void onFailure(Call<ServiceData> call, Throwable t) {
Log.e(TAG, "" + t);
}
});
You call and waiting for List. Call<ArrayList<ServiceData>>
But in the response, you have an object.
[...] - is array (list)
{...} - is object
You need to create classes for all parameters properly.
Just try to look at this service (or similar):
http://www.jsonschema2pojo.org/
Or Android Studio (IDEA) also has a plugin (GsonFormat) for converting JSON.

Android - Retrofit2 - java.security.cert.CertPathValidatorException: Trust anchor for certification path not found

I want to get data from the server (https://data.egov.kz/api/v2/zheke_zhane_zandy_tulgalardy_k1/v6?pretty) as an array of json objects. But I get this Log:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
I am using Retrofit2 and here my code:
MainActivity.java
public class MainActivity extends AppCompatActivity
implements GetAdmissionSchedule.GetAdmissionScheduleInterface {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetAdmissionSchedule getAdmissionSchedule = new GetAdmissionSchedule(this);
getAdmissionSchedule.getAdmissionScheduleList();
}
#Override
public void getAdmissionSchedule(List<AdmissionSchedule> admissionScheduleList) {
// here i get my data
}
}
GetAdmissionSchedule.java
public class GetAdmissionSchedule {
private GetAdmissionScheduleInterface getAdmissionScheduleInterface;
public GetAdmissionSchedule(GetAdmissionScheduleInterface getAdmissionScheduleInterface) {
this.getAdmissionScheduleInterface = getAdmissionScheduleInterface;
}
public interface GetAdmissionScheduleInterface {
void getAdmissionSchedule(List<AdmissionSchedule> admissionScheduleList);
}
public void getAdmissionScheduleList() {
DataEgovApi service = DataEgovBaseURL.getRetrofit();
Call<List<AdmissionSchedule>> call = service.getAdmissionScheduleList();
call.enqueue(new Callback<List<AdmissionSchedule>>() {
#Override
public void onResponse(Call<List<AdmissionSchedule>> call, Response<List<AdmissionSchedule>> response) {
Log.d("MyLogs", "MVD: getAdmissionScheduleList " + response.code());
getAdmissionScheduleInterface.getAdmissionSchedule(response.body());
}
#Override
public void onFailure(Call<List<AdmissionSchedule>> call, Throwable t) {
Log.d("MyLogs", "MVD: getAdmissionScheduleList " + t.getLocalizedMessage());
getAdmissionScheduleInterface.getAdmissionSchedule(null);
}
});
}
}
DataEgovBaseURL.java
public class DataEgovBaseURL {
private static final String BASE_URL = "https://data.egov.kz/";
private static Retrofit retrofit = null;
public static DataEgovApi getRetrofit() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit.create(DataEgovApi.class);
}
}
DataEgovApi.java
public interface DataEgovApi {
#GET("api/v2/zheke_zhane_zandy_tulgalardy_k1/v6?pretty")
Call<List<AdmissionSchedule>> getAdmissionScheduleList();
}
AdmissionSchedule.java (My POJO class)
public class AdmissionSchedule {
#SerializedName("id")
#Expose
private String id;
#SerializedName("vremia")
#Expose
private String vremia;
#SerializedName("adres_ru")
#Expose
private String adresRu;
#SerializedName("doljnost_ru")
#Expose
private String doljnostRu;
#SerializedName("name_ru")
#Expose
private String nameRu;
#SerializedName("data")
#Expose
private String data;
#SerializedName("adres_kz")
#Expose
private String adresKz;
#SerializedName("doljnost_kz")
#Expose
private String doljnostKz;
#SerializedName("name_kz")
#Expose
private String nameKz;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVremia() {
return vremia;
}
public void setVremia(String vremia) {
this.vremia = vremia;
}
public String getAdresRu() {
return adresRu;
}
public void setAdresRu(String adresRu) {
this.adresRu = adresRu;
}
public String getDoljnostRu() {
return doljnostRu;
}
public void setDoljnostRu(String doljnostRu) {
this.doljnostRu = doljnostRu;
}
public String getNameRu() {
return nameRu;
}
public void setNameRu(String nameRu) {
this.nameRu = nameRu;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getAdresKz() {
return adresKz;
}
public void setAdresKz(String adresKz) {
this.adresKz = adresKz;
}
public String getDoljnostKz() {
return doljnostKz;
}
public void setDoljnostKz(String doljnostKz) {
this.doljnostKz = doljnostKz;
}
public String getNameKz() {
return nameKz;
}
public void setNameKz(String nameKz) {
this.nameKz = nameKz;
}
}
You server url is https and certificate is already not valid.
Change https to http and it will work.
Else you can install valid SSL certificate on the server.

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 do I correctly use Json Reader to navigate in my Json using retrofit 2?

Here is my API
http://services.groupkt.com/country/get/all
I'm confused on how to use the Json reader methods. I tried looking on its Javadoc, it seems the straightforward but when I implement it, it has different behavior.
Here is my code
RestResponse result = null;
String countryName = null;
String alpha2Code = null;
String alpha3Code = null;
jsonReader.beginObject();
jsonReader.beginArray();
while (jsonReader.hasNext()) {
countryName = jsonReader.nextString();
alpha2Code = jsonReader.nextString();
alpha3Code = jsonReader.nextString();
}
jsonReader.endArray();
jsonReader.beginArray();
while (jsonReader.hasNext()) {
jsonReader.beginObject();
while (jsonReader.hasNext()) {
jsonReader.skipValue();
jsonReader.peek();
}
jsonReader.endObject();
}
jsonReader.endArray();
This is my code for learning how does it navigates my json. This code runs on the read method of TypeAdapter.
Can you provide me samples on how can I easily understand how to use json reader methods correctly?
If you want to learn basic jSON parsing you should definitely read this Android Json Parsing ..... but in retrofit 2 you can use Model classes rather than json parsing.....I'm sharing my code below....
Model Class
public class WeatherResponse {
#SerializedName("cod")
#Expose
private String cod;
#SerializedName("message")
#Expose
private Double message;
#SerializedName("cnt")
#Expose
private Double cnt;
#SerializedName("list")
#Expose
private List<cityList> list = null;
#SerializedName("city")
#Expose
private City city;
public String getCod() {
return cod;
}
public void setCod(String cod) {
this.cod = cod;
}
public Double getMessage() {
return message;
}
public void setMessage(Double message) {
this.message = message;
}
public Double getCnt() {
return cnt;
}
public void setCnt(Double cnt) {
this.cnt = cnt;
API Client
public class ApiClient {
private static final int TIME_OUT = 30;
public static final String BASE_URL = "http://api.openweathermap.org/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
OkHttpClient.Builder okBuilder = new OkHttpClient.Builder();
okBuilder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
okBuilder.readTimeout(TIME_OUT, TimeUnit.SECONDS);
okBuilder.writeTimeout(TIME_OUT, TimeUnit.SECONDS);
Gson gson = new GsonBuilder().create();
return new Retrofit.Builder()
.baseUrl(BASE_URL) .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okBuilder.build())
.build();
}
return retrofit;
}
}
API Interface
public interface ApiInterface {
#GET("data/2.5/forecast?id=524901")
Call<WeatherResponse> getWeatherData(#Query("APPID") String apiKey);
}
Be easy, just try GSON. There are many examples, articles about that
https://guides.codepath.com/android/Consuming-APIs-with-Retrofit#overview
https://medium.freecodecamp.com/rxandroid-and-retrofit-2-0-66dc52725fff#.ymmfqdi9s
https://zeroturnaround.com/rebellabs/getting-started-with-retrofit-2/
According http://services.groupkt.com/country/get/all response here is GSON models
public class County {
#SerializedName("name") public String name;
#SerializedName("alpha2_code") public String alpha2Code;
#SerializedName("alpha3_code") public String alpha3Code;
}
public class RestResponse {
#SerializedName("messages") public Messages messages;
#SerializedName("result") public Countries counties;
}
public class CountriesResponse {
#SerializedName("RestResponse") public RestResponse restResponse;
}
public interface GroupktApi {
#GET("/country/get/all")
Call<CountriesResponse> getAllCountries()
}
public Gson provideGson() {
return new GsonBuilder().registerTypeAdapter(Messages.class, MessagesDeserializer());
}
public class MessagesDeserializer extend JsonDeserializer<Messages> {
#Override public Messages deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
List<String> messages = new ArrayList();
if (json.isJsonArray()) {
Type listType = new TypeToken<ArrayList<String>>(){}.getType();
List<String> arrayMessages = context.deserialize<List<String>>(value, listType)
messages.addAll(arrayMessages)
} else {
String message = json.asString()
messages.add(message)
}
return new Messages(messages);
}
}
public class Messages {
public List<String> messages;
public Messages (List<String> messages) {
this.messages = messages;
}
}
Countries in the same way
That's it

Android Parcelable JsonArray in Side JsonObject

When i am trying Parce this json data with GSON. I am unable to get JsonArray in side of JsonObject. Below is my code, every suggestion will get appriciated.
JSON DATA FROM SERVER :
{
"GetJobDetails": {
"MaxAmount": 0,
"CreatorId": 1,
"JobImages": [
{
"ImagePath": "http://192.168.1.108:8088/Uploads/6e660c0c-4a2b- 42dc-ad97-82cc3efe87a0.jpg",
"JobImageId": 1
},
{
"ImagePath": "http://192.168.1.108:8088/Uploads/ccf1087d-9f7e-4c21-bc61-8aa3fd924e05.jpg",
"JobImageId": 2
},
{
"ImagePath": "http://192.168.1.108:8088/Uploads/4333e8b6-0079-457f-a225-fd7900ea81b1.jpg",
"JobImageId": 3
}
],
}
}
In ACTIVITY :
Gson gson = new Gson();
String response = new String(mresponce);
JobDetails jobDetails= gson.fromJson(response, JobDetails .class);
Log.e("JobDetails ",""+jobDetails.getJobImagesList());
this log prints allways null even when i have images list there in my data.
MODEL CLASS :
public class JobDetails implements Parcelable {
private int MaxAmount;
private int CreatorId;
private List<JobImage> JobImages;
public JobDetails() {
}
public JobDetails(Parcel parcel) {
this.MaxAmount = parcel.readInt();
this.CreatorId= parcel.readInt();
this.JobImages = new ArrayList<JobImage>();
parcel.readTypedList(JobImages, JobImage.CREATOR);
}
// Parcelable
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.MaxAmount);
dest.writeInt(this.CreatorId);
dest.writeList(this.JobImages);
// TODO: Not Parceling AddressList
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public JobDetails createFromParcel(Parcel in) {
return new JobDetails(in);
}
public JobDetails[] newArray(int size) {
return new JobDetails[size];
}
};
public List<JobImage> getJobImagesList() {
return JobImages;
}
public void setJobImagesList(List<JobImage> jobImages) {
JobImages = jobImages;
}
public int getMaxAmount() {
return MaxAmount;
}
public void setMaxAmount(int maxAmount) {
MaxAmount= maxAmount;
}
}
ANOTHER MODEL CLASS FOR JOBIMAGE:
public class JobImage implements Parcelable {
private String ImagePath;
private int JobImageId;
JobImage(){
}
public JobImage(Parcel in) {
this.ImagePath = in.readString();
this.JobImageId = in.readInt();
}
// Parcelable
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.ImagePath);
dest.writeInt(this.JobImageId);
// TODO: Not Parceling AddressList
}
public static final Creator CREATOR = new Creator() {
public JobImage createFromParcel(Parcel in) {
return new JobImage(in);
}
public JobImage[] newArray(int size) {
return new JobImage[size];
}
};
public String getImagePath() {
return ImagePath;
}
public void setImagePath(String imagePath) {
ImagePath = imagePath;
}
public int getJobImageId() {
return JobImageId;
}
public void setJobImageId(int jobImageId) {
JobImageId = jobImageId;
}
}
Please help me to find what i am doing wrong in this :
Your top-level JSON object is not a JobDetails object, it is an object that has JobDetails member name GetJobDetails. You need to handle this level of your JSON. You can do it with a custom TypeAdapter, or perhaps easier, just make a container object and deserialize it.
class JobDetailContainer {
private JobDetails GetJobDetails;
public JobDetails getJobDetails() {
return GetJobDetails;
}
}
then use --
Gson gson = new Gson();
String response = new String(mresponce);
GetJobDetails getJobDetails= gson.fromJson(response, GetJobDetails.class);
Log.e("JobDetails ",""+getJobDetails.getJobDetails().getJobImagesList());
Agreed with #iagreen ...I should handel top level json object too..this is what i have done after doing some R&D
public class GetJobDetails {
public GetJobDetailsResult getGetJobDetailsResult() {
return GetJobDetailsResult;
}
public void setGetJobDetailsResult(GetJobDetailsResult GetJobDetailsResult) {
this.GetJobDetailsResult = GetJobDetailsResult;
}
}
For Inner Json :
public class GetJobDetailsResult {
private Integer MaxAmount;
private Integer CreatorTotJobPosted;
private List<JobImage> JobImages = new ArrayList<JobImage>();
public Integer getMaxAmount() {
return MaxAmount;
}
public void setMaxAmount(Integer MaxAmount) {
this.MaxAmount = MaxAmount;
}
public Integer getCreatorTotJobPosted() {
return CreatorTotJobPosted;
}
public void setCreatorTotJobPosted(Integer CreatorTotJobPosted) {
this.CreatorTotJobPosted = CreatorTotJobPosted;
}
public List<JobImage> getJobImages() {
return JobImages;
}
public void setJobImages(List<JobImage> JobImages) {
this.JobImages = JobImages;
}
}
Finally For To Hold JobImages
public class JobImage {
private String ImagePath;
private Integer JobImageId;
public String getImagePath() {
return ImagePath;
}
public void setImagePath(String ImagePath) {
this.ImagePath = ImagePath;
}
public Integer getJobImageId() {
return JobImageId;
}
public void setJobImageId(Integer JobImageId) {
this.JobImageId = JobImageId;
}
}
Final Step :
Gson gson = new Gson();
String response = new String(jsonObjectresponce.toString());
GetJobDetails getJobDetails = gson.fromJson(response, GetJobDetails.class);
GetJobDetailsResult result = getJobDetails.getGetJobDetailsResult();
// now result object contains my json data.

Categories