How to use Retrofit2 to parse json into class with subclass(es) - java

How to convert given json response
{
"name" : "John",
"surname" : "Doe",
"location" : {
"name" : "Paris",
"desc" : "Welcome to Paris"
}
}
into
class Person
{
String name;
String surname;
Location location; // new Location(String name, String desc)
}
It's all about nested Location class that is inside Person class

Use #Expose or #SerializedName annotation like
class Person
{
#SerializedName("name")
String name;
#SerializedName("surname")
String surname;
#SerializedName("location")
Location location; // new Location(String name, String desc)
}
and Location class like
class Location
{
#SerializedName("name")
String name;
#SerializedName("desc")
String desc;
}
Add getter and setter method for accessing data

Use a combination of Gson + Retrofit.
First of all use the annotation #SerializedName("yourFieldName") that Retrofit provides in the fields of your model class.
Init your Gson configuration with a RuntimeTypeAdapterFactory:
RuntimeTypeAdapterFactory<Person> itemFactory = RuntimeTypeAdapterFactory
.of(Person.class) // The field that defines the type
.registerSubtype(Location.class, "location")
.registerSubtype(YourSubclass.class) // if the flag equals the class name, you can skip the second parameter.
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(itemFactory)
.create();
Then you init Retrofit:
Retrofit.Builder builder = new Retrofit.Builder();
builder.baseUrl(BASE_URL);
builder.addConverterFactory(GsonConverterFactory.create(gson));
Retrofit retrofit = builder.build();

First get an API and get its JSON output by Advance REST Client which is a Chrome Extension. Now put that output to JSON to POJO converter
and you'll get your POJO Classes. Paste them to your project. Make an interface`
/**
* Get Data
*
* #param body Holds the JSON payloads
* #return Formatted data
*/
#POST("JobSpotAPI/getUserInterviewSchedule")
Call<POJOClass> getData(#Body JsonObject body);
and setup a Client
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
Create a Recycler view setup its adapter and all. Just add a few new methods like-
public void updateAnswers(List<Item> items) {
mItems = items;
notifyDataSetChanged();
}
private Item getItem(int adapterPosition) {
return mItems.get(adapterPosition);
}
Setup Utility class to call the interface.
public class ApiUtils {
public static final String BASE_URL = "https://base_url/";
public static Interface_name methodName() {
return RetrofitClient.getClient(BASE_URL).create(Interface_name.class);
}}
Declare the Interface in your Activity
Interface_name obj = ApiUtils.methodName();
If you have some payloads then attach them to you request. Before that you need a JSON string to pass to API request. To make a JSON Payload.
private JsonObject makeJsonObjectPayload() {
JsonObject requestBean = new JsonObject();
requestBean.addProperty("key", value);
requestBean.addProperty("key", value);
requestBean.addProperty("key", value);
requestBean.addProperty("key", value);
return requestBean;
Pass the API request
obj.getData(makeJsonObjectPayload()).enqueue(new Callback<POJOClass>() {
#Override
public void onResponse(Call<POJOClass> call, Response<POJOClass> response) {
if(response.isSuccessful()) {
mAdapter.updateAnswers(response.body().getItems());
Log.d("MainActivity", "posts loaded from API");
}else {
int statusCode = response.code();
// handle request errors depending on status code
}
}
#Override
public void onFailure(Call<UserDataPOJOClass> call, Throwable t) {
//showErrorMessage();
Log.d("API ERROR",""+t.getMessage());
Log.d("MainActivity", "error loading from API");
}
});

Related

How to get JSON data by POST method with Secret code in android studio

I need to get json data response based on SECRET CODE with POST method, would you please solve my issue, thanks in advance.
I have been facing with many problems with this POST method of Secret Code to get the JSON Response
public class MainActivity extends AppCompatActivity {
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listViewHeroes);
getQuestions();
}
private void getQuestions() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiInterface.BASE_URL)
.addConverterFactory(GsonConverterFactory.create()) //Here we are using the GsonConverterFactory to directly convert json data to object
.build();
ApiInterface api = retrofit.create(ApiInterface.class);
RequestModel requestModel = new RequestModel();
requestModel.setSecretCode("341977082");
Call<List<ModelObjects>> call = api.getQuestions();
call.enqueue(new Callback<List<ModelObjects>>() {
#Override
public void onResponse(Call<List<ModelObjects>> call, Response<List<ModelObjects>> response) {
List<ModelObjects> questionsList = response.body();
String[] questions = new String[questionsList.size()];
for (int i = 0; i < questionsList.size(); i++) {
questions[i] = questionsList.get(i).getQues_No();
}
listView.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, questions));
}
#Override
public void onFailure(Call<List<ModelObjects>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});}}
Here is the interface and where I am passing the URL that contains parent and extension
public interface ApiInterface {
String BASE_URL = "";
#POST("QuestionsList")
Call<List<ModelObjects>> getQuestions();}
Here is the response Model
public class ModelObjects {
#SerializedName("Ques_No")
private String Ques_No;
public ModelObjects(String ques_No) {
Ques_No = ques_No;
}
public String getQues_No() {
return Ques_No;
}
public void setQues_No(String ques_No) {
Ques_No = ques_No;
}}
Here is the Request Model
public class RequestModel {
private String SecretCode;
public RequestModel(String secretCode) {
SecretCode = secretCode;
}
public RequestModel() {
}
public String getSecretCode() {
return SecretCode;
}
public void setSecretCode(String secretCode) {
SecretCode = secretCode;
}}
Here you have defined RequestModel but you are not passing it to the api call. Post request should have body.
So specify #Body while defining the api call as below.
#POST("QuestionsList")
Call<List<ModelObjects>> getQuestions(#Body RequestModel model);
Then while calling the getQuestion() pass the model.
RequestModel requestModel = new RequestModel();
requestModel.setSecretCode("341977082");
Call<List<ModelObjects>> call = api.getQuestions(requestModel);
Update :
update your ModelObject as below.
public class ModelObjects {
#SerializedName("Ques_No")
String Ques_No;
#SerializedName("Question")
String Ques;
#SerializedName("Answer")
String answer;
//same for other params as well
}
What can i see it, you are creating object of RequestModel class, but you are not passing it anywhere. If you want to send the secretCode along with the post network call, then you'll have to pass this requestModel instance to the call.
public interface ApiInterface {
String BASE_URL = "";
#POST("QuestionsList")
Call<List<ModelObjects>> getQuestions(#Body RequestModel requestModel);
}
then you can call this method and can pass this requestModel Object by
Call<List<ModelObjects>> call = api.getQuestions(requestModel);
If you want to access the first object you can do it by
List<ModelObjects> questionsList = response.body();
ModelObject obj = questionList.get(0);
String question = obj.getQues_No();
This question is going to be the first question.

How to get data from object in JSON response in Fragment

How to get "description" from GET method in retrofit android with Fragment or xml and Retrofit interface and retrofit client ,full code actually i've face some issues.
I'm trying some time but i can't fix this API.
JSON response.
{
"statuscode": 200,
"status": "true",
"cmsDetails": {
"id": 2,
"title": "Privacy Policy",
"description": "<p>We, Devoid Technologies Pvt. Ltd., incorporated."
}
}
Retrofit Interface
#GET("retrieve/policy")
Call<CMSDetails> getDescription();
I want get Description in cmsDetails object.
Create a model for the JSON Response like this :
public class CMS
{
#SerializedName("statuscode")
private String statuscode;
#SerializedName("status")
private String status;
#SerializedName("cmsDetails")
private CmsDetails cmsDetails;
public CmsDetails getCmsDetails()
{
return cmsDetails;
}
}
Now create another model for CmsDetails:
public class CmsDetails
{
#SerializedName("id")
private int id;
#SerializedName("title")
private String title;
#SerializedName("description")
private String description;
public String getDescription()
{
return description;
}
}
Now create your endpoint like this:
public interface EndPoints {
#GET("retrieve/policy")
Call<CMS> getDescriptionCms();
}
Now create the client as follows :
public class RetroFitCMSClient {
private static Retrofit retrofit;
private static OkHttpClient okClient;
private static final String BASE_URL = "http://test.test;
public static Retrofit getRetrofitInstance() {
okClient = new OkHttpClient
.Builder()
.build();
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Now you can make your call retrofit call and get the description like this :
EndPoints service = RetroFitCMSClient.getRetrofitInstance().create(EndPoints.class);
call = service.getDescriptionCms();
call.enqueue(new Callback<CMS>() {
#Override
public void onResponse(Call<CMS> call, Response<CMS> response) {
if(response.isSuccessful()) {
String description = response.body().getCmsDetails().getDescription();
}
}
#Override
public void onFailure(Call<CMS> call, Throwable throwable) {
}
}

How to parse JSON using GSON in android

I am developing an application where I want to hit the web services and get the data. I am using Google Volley to hit the web service. I am doing it all right but unable to parse JSON using GSON. I am unable to understand where I am doing it wrong.
Here is the URL of Web Services
Here is what I am doing
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.GET,
"https://api.github.com/repos/crashlytics/secureudid/issues",
null,
new MyListner(),
new MyErrorListner()
);
requestQueue.add(jsonObjectRequest);
}
class MyListner implements Response.Listener<JSONObject>
{
#Override
public void onResponse(JSONObject response) {
Gson gson = new Gson();
Results results = gson.fromJson(response.toString(), Results.class);
for(Test t : results.getmResults())
{
Log.e("Tag", t.toString());
}
}
}
class MyErrorListner implements Response.ErrorListener
{
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", error.getMessage());
}
}
The other classes are given below
public class Results {
private ArrayList<Test> mResults;
public void setResults(ArrayList<Test> results)
{
mResults = results;
}
public ArrayList<Test> getmResults()
{
return mResults;
}
}
public class Test {
#SerializedName("title")
private String mTitle;
#SerializedName("user")
private User mUser;
#SerializedName("created_at")
private String mCreatedAt;
#SerializedName("body")
private String mBody;
#SerializedName("updated_at")
private String mUpdatedAt;
public String getmBody() {
return mBody;
}
public void setmBody(String mBody) {
this.mBody = mBody;
}
public String getmUpdatedAt() {
return mUpdatedAt;
}
public void setmUpdatedAt(String mUpdatedAt) {
this.mUpdatedAt = mUpdatedAt;
}
public String getmCreatedAt() {
return mCreatedAt;
}
public void setmCreatedAt(String mCreatedAt) {
this.mCreatedAt = mCreatedAt;
}
public User getmUser() {
return mUser;
}
public void setmUser(User mUser) {
this.mUser = mUser;
}
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
#Override
public String toString() {
return mTitle + " " + mBody + " " + mCreatedAt + " " + mUpdatedAt + " " + mUser.getmLogin() + " ";
}
}
public class User {
#SerializedName("login")
private String mLogin;
public String getmLogin() {
return mLogin;
}
public void setmLogin(String mLogin) {
this.mLogin = mLogin;
}
}
Here is the error what I am getting
org.json.JSONException: Value [{"url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28","repository_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid","labels_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28\/labels{\/name}","comments_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28\/comments","events_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28\/events","html_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28","id":222258999,"number":28,"title":"Fix broken headings in Markdown files","user":{"login":"bryant1410","id":3905501,"avatar_url":"https:\/\/avatars3.githubusercontent.com\/u\/3905501?v=4","gravatar_id":"","url":"https:\/\/api.github.com\/users\/bryant1410","html_url":"https:\/\/github.com\/bryant1410","followers_url":"https:\/\/api.github.com\/users\/bryant1410\/followers","following_url":"https:\/\/api.github.com\/users\/bryant1410\/following{\/other_user}","gists_url":"https:\/\/api.github.com\/users\/bryant1410\/gists{\/gist_id}","starred_url":"https:\/\/api.github.com\/users\/bryant1410\/starred{\/owner}{\/repo}","subscriptions_url":"https:\/\/api.github.com\/users\/bryant1410\/subscriptions","organizations_url":"https:\/\/api.github.com\/users\/bryant1410\/orgs","repos_url":"https:\/\/api.github.com\/users\/bryant1410\/repos","events_url":"https:\/\/api.github.com\/users\/bryant1410\/events{\/privacy}","received_events_url":"https:\/\/api.github.com\/users\/bryant1410\/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-04-17T23:26:47Z","updated_at":"2017-04-17T23:26:47Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/pulls\/28","html_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28","diff_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28.diff","patch_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28.patch"},"body":"GitHub changed the way Markdown headings are parsed, so this change fixes it.\n\nSee [bryant1410\/readmesfix](https:\/\/github.com\/bryant1410\/readmesfix) for more information.\n\nTackles bryant1410\/readmesfix#1\n"},{"url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13","repository_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid","labels_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13\/labels{\/name}","comments_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13\/comments","events_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13\/events","html_url":"https:\/\/github.com\/crashlytics\/secureudid\/issues\/13","id":3923240,"number":13,"title":"Not working with ARC","user":{"login":"SaschaMoellering","id":1321549,"avatar_url":"https:\/\/avatars0.githubusercontent.com\/u\/1321549?v=4","gravatar_id":"","url":"https:\/\/api.github.com\/users\/SaschaMoellering","html_url":"https:\/\/github.com\/SaschaMoellering","followers_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/followers","following_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/following{\/other_user}","gists_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/gists{\/gist_id}","starred_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/starred{\/owner}{\/repo}","subscriptions_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/subscriptions","organizations_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/orgs","repos_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/repos","events_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/events{\/privacy}","received_events_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"20
You are trying to parse an array of object (from your webservices) to an object containing a property mResults which is an array of object (Test);
Instead of using Results class during parsing you need to directly use an ArrayList of Test:
Results results = gson.fromJson(response.toString(), Results.class);
should be
ArrayList<Test> results = gson.fromJson(response.toString(), new TypeToken<ArrayList<Test>>(){}.getType());
As ArrayList is a generic it's not possible to use ArrayList<Test>.class to get a representation of the data type, we must use TypeToken. What is TypeToken?
TypeToken represents a generic type T. Java doesn't yet provide a way to
represent generic types, so this class does. Forces clients to create
a subclass of this class which enables retrieval the type information
even at runtime.
getType returns the type of the class used to build TypeToken and so we can use it in gson fromJson() parsing method.
--
Second problem:
Your are using JsonObjectRequest but server response is a Json array so you need to use JsonArrayRequest and so update MyListner to use JSONArray instead of JSONObject.
BUT
As your are parsing server response manually you can use StringRequest and so avoid parsing step of Volley.
StringRequest jsonObjectRequest = new StringRequest(
Request.Method.GET,
"https://api.github.com/repos/crashlytics/secureudid/issues",
new MyListner(),
new MyErrorListner()
);
and MyListner is now directly using String:
class MyListner implements Response.Listener<String> {
#Override
public void onResponse(String response) {
Gson gson = new Gson();
ArrayList<Test> results = gson.fromJson(response, new TypeToken<ArrayList<Test>>() {}.getType());
for (Test t : results) {
Log.e("Tag", t.toString());
}
}
}

Volley REST client using JSON

I want to interact with a RESTful webservice that responds only in JSON.
Any successful response from the server has this syntax:
{
"code": int code,
"data": object or list of objects
}
while on error response:
{
"code": int code,
"error": string,
"details": string
}
So I made two classes in my Android project like this (for GSON reflection):
public class ErrorEntity {
private String details;
private String error;
private int code;
public ErrorEntity() {
// Stub constructor
}
public String getDetails() {
return details;
}
public String getError() {
return error;
}
public int getCode() {
return code;
}
}
For a successful response I made a generic because I don't want to parse JSON data on overridden parseNetworkResponse:
public class SuccessfulEntity<T> {
private T data;
private int code;
public SuccessfulEntity() {
// Stub content
}
public T getData() {
return data;
}
public int getCode() {
return code;
}
}
Now, because my RESTful server requires some custom headers, I need to make a Request subclass, but I don't know from which class I need to inherit.
I saw this question: Send POST request with JSON data using Volley and though to do something like that.
Basically, I want to make a new class (VolleyRestClient) which has GET, POST, DELETE methods and API routings, and with this class make all requests I need to do.
Methods of this class need to make a new custom request and parse new objects response like SuccessfulEntity and ErrorEntity, and then parsing data in service/thread that make the VolleyRestClient call.
How can I do that?
After a long fight with generics and type erasure, I finally did it.
So I'm posting this for whoever has the same issue like me and needs a solution without freaking out.
My ErrorEntity and my SuccessfulEntity are still the same, but I created a new interface called RepositoryListener, like this:
public interface RepositoryListener {
public abstract void onErrorResponse(int code, String details);
public abstract void onSuccessfulResponse(int code, Object obj);
public abstract void onSuccessfulResponse2(int code, List<Object> obj);
}
Then I made a class, VolleyRestClient, like this:
public class VolleyRestClient extends RestClient {
private final DefaultRetryPolicy mRetryPolicy;
private final RequestQueue mQueue;
private final Gson gson = new Gson();
public VolleyRestClient(Context context) {
// Default retry policy
mRetryPolicy = new DefaultRetryPolicy(2000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
mQueue = Volley.newRequestQueue(context);
}
public RequestQueue getQueue() {
// Method to push requests for image download
return mQueue;
}
#Override
public void GET(boolean obj, boolean needAuth, String url, Type type,
RepositoryListener listener) {
// Choose which listener to construct
Response.Listener<myResponse> mListener = obj ?
// This uses objects
makeSuccessfulListener(listener, type) :
// This uses list of objects
makeSuccessfulListener2(listener, type);
myRequest mRequest =
new myRequest(Request.Method.GET, needAuth, url,
mListener, makeErrorListener(listener));
mRequest.setRetryPolicy(mRetryPolicy);
mQueue.add(mRequest);
}
#Override
public void POST(boolean needAuth, String url, String body, Type type, RepositoryListener listener) {
myRequest mRequest = new myRequest(Request.Method.POST, needAuth, url, body,
makeSuccessfulListener(listener, type), makeErrorListener(listener));
mRequest.setRetryPolicy(mRetryPolicy);
mQueue.add(mRequest);
}
#Override
public void DELETE(boolean needAuth, String url, Type type, RepositoryListener listener) {
myRequest mRequest =
new myRequest(Request.Method.DELETE, needAuth, url,
makeSuccessfulListener(listener, type), makeErrorListener(listener));
mRequest.setRetryPolicy(mRetryPolicy);
mQueue.add(mRequest);
}
private Response.Listener<myRequest> makeSuccessfulListener
(final RepositoryListener listener, final Type type) {
// TODO: test this method and implement lists
if (listener == null) {
return null;
} else {
return new Response.Listener<myRequest>() {
#Override
public void onResponse(myRequest response) {
SuccessfulEntity<Object> obj = gson.fromJson(response.getBody(), type);
listener.onSuccessfulResponse(response.getCode(), obj.getData());
}
};
}
}
private Response.Listener<myRequest> makeSuccessfulListener2
(final RepositoryListener listener, final Type type) {
// TODO: test lists
if (listener == null) {
return null;
} else {
return new Response.Listener<myRequest>() {
#Override
public void onResponse(myReqyest response) {
SuccessfulEntity<List<Object>> obj = gson.fromJson(response.getBody(), type);
listener.onSuccessfulResponse2(response.getCode(), obj.getData());
}
};
}
}
private Response.ErrorListener makeErrorListener(final RepositoryListener listener) {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
String jError = new String(error.networkResponse.data);
ErrorEntity mError = gson.fromJson(jError, ErrorEntity.class);
// Invoke listener closure
listener.onErrorResponse(error.networkResponse.statusCode, mError.getDetails());
} catch (Exception e) {
listener.onErrorResponse(404, e.getMessage());
}
}
};
}
}
This is very dependant by my needs, but I'll explain the general concept.
So I have a custom request, as explained in my question, and I want to parse it to the correct data type.
To be more specific, I could have a JSONArray data only on GET requests (paginated elements, etc...) so I need to find a way to distinguish between this two cases (of course, I know in which cases I'll get a List or an Object).
We cannot simply create POJO from Json within a generic class using its type (because Java Type Erasure), so we need object type upfront.
But what we can do is:
in our custom request, on parseNetworkResponse, do something like that:
#Override
protected Response<myResponse> parseNetworkResponse(NetworkResponse response) {
try {
// Using server charset
myResponse mResponse = new myResponse();
mResponse.setCode(response.statusCode);
mResponse.setBody(new String(response.data,
HttpHeaderParser.parseCharset(response.headers)));
// Return new response
return Response.success(mResponse, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
// Normally use 'utf-8'
return Response.error(new ParseError(e));
}
}
In other words, copy the raw string response body onto a new object myResponse;
Response body will be eventually parsed in VolleyRestClient with the appropriate type passed as a GET/DELETE/POST argument;
makeSuccessfulListener and makeSuccessfulListener2 construct a Response.Listener from a RepositoryListener, which has 3 methods to override: onSuccessfulResponse for objects data, onSuccessfulResponse2 for list of objects data, onErrorResponse for 4XX/5XX errors;
Our data object/list will be parsed to more generics type (List and Object) and then passed to our custom listener RepositoryListener.
A full example for this approach:
public void getNewLogin(String nickname, String password,
final TextView author, final TextView title, final TextView text) {
String json =
(new StringBuilder()
.append("{ \"nickname\": \"")
.append(nickname)
.append("\", \"password\": \"")
.append(password)
.append("\" }")).toString();
mRest.POST(false, "http://192.168.0.104:8000/api/session", json,
new TypeToken<SuccessfulEntity<Login>>(){}.getType(),
new RepositoryListener() {
#Override
public void onSuccessfulResponse2(int code, List<Object> obj) {
// Nothing happens here
}
#Override
public void onSuccessfulResponse(int code, Object obj) {
UserSession mInstance = UserSession.getInstance(null);
Login newLogin = (Login) obj;
title.setText(newLogin.getToken());
mInstance.setToken(newLogin.getToken());
Log.i("onSuccessfulResponse", mInstance.getToken());
Log.i("onSuccessfulResponse", mInstance.getmAuthorizationToken());
if (newLogin.getUser() != null) {
author.setText(newLogin.getUser().getNickname());
text.setText(newLogin.getUser().getUniversity());
}
}
#Override
public void onErrorResponse(int code, String error) {
Log.i("onErrorResponse", error);
}
});
mRest is a VolleyRestClient object, which performs a POST request to that address with Type constructed by Gson TypeToken (remember, our body is a SuccessfulEntity).
Since we'll have an Object data for sure, we'll just override onSuccessfulResponse, cast data object to the same type T of SuccessfulEntity used in TypeToken, and do our dirty work.
I don't know if I was clear, this approach works, if some of you needs some clarification, just ask :)

JSON parsing only one branch of whole message java using GsonBuilder and InputStream Android

I just try to integrate with external webservice via JSON from Android. I receive following JSON format:
Data that i'm interested in is in "messages" branch.
To access data i'm using :
builder.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY);
Gson gson = builder.create();
ClassToStore response = gson.fromJson(reader, ClassToStore.class);
where reader is a input stream from:
am = getInstrumentation().getContext().getAssets();
am.open("data.json");
Message structure looks like:
ClassToStore has all fields with the same names.
I get all objects but all of theme are null's
PLEASE HELP :(
My classToStore:
public static class ClassToStore implements Serializable {
private static final long serialVersionUID = -1463052486583654136L;
public String id ;
public String replied_to_id ;
public String sender_id ;
public String created_at ;
public String getId() {
return id;
}
public String getReplied_to_id() {
return replied_to_id;
}
public String getSender_id() {
return sender_id;
}
public String getCreated_at() {
return created_at;
}
}
You will need an extra class to match the outer object:
public class OuterObject {
List<ClassToStore> messages;
}
And then load it like this:
Gson gson = new Gson();
Type type = new TypeToken<List<OuterObject>>(){}.getType();
List<OuterObject> outerList = gson.fromJson(reader, type);
List<ClassToStore> listOfMessages = outerlist.get(0).messages;

Categories

Resources