Retrofit - Can I map response data fields? - android

I'm testing/creating a REST client to the new Basecamp API using Retrofit. It looks something like this:
class Project {
String name;
String appUrl;
}
interface Basecamp {
#GET("/projects.json")
List<Project> projects();
}
In the json response, the source field for appUrl is called app_url. Asides from renaming the field in the class, is there a simple way to map the response data with my data structure?

So I found the answer in this question. Turns out this can be solved using Gson:
class Project {
String name;
#SerializedName("app_url")
String appUrl;
}

If you are using Jackson for JSON parsing with Retrofit you can use the #JsonProperty annotation:
Example:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonIgnoreProperties (ignoreUnknown = true)
class Project {
#JsonProperty("name")
String name;
#JsonProperty("app_url")
String appUrl;
}

Related

Exclude some fields from JSON Body in POST request using Retrofit Android

I am using Retrofit2 to send and receive requests to my server.
Here are my API interface and Model class.
Interface
public interface ApiInterface {
#POST("/users/")
Call<User> signUp(#Body User user);
#POST("/login_url/")
Call<User> login(#Body User user);
}
Retrofit client
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getRestClient(String baseUrl) {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
POJO class
public class User {
#SerializedName("id")
private Integer id;
#SerializedName("email")
#Expose
private String email;
#SerializedName("first_name")
private String firstName;
#SerializedName("last_name")
private String lastName;
#SerializedName("password")
#Expose
private String password;
}
I have exposed email and password so that in login request these 2 parameters will be added.
But for another request like Sign up, I required a first name and last name also to be sent along with email and password.
Can I use same "User" class for both ? because if I expose the first name and last name then, those fields will be also sent in login request.
Is there any other way or should I make different POJO classes for both request ?
Instead of sending the whole class , you can use #Field annotation , so your login callback will be something like this :
#FormUrlEncoded
#POST("/login_url/")
Call<User> login(#field("email")String email,#field("password")String password);
#FormUrlEncoded denotes that the request body will use form URL encoding. Fields should be declared as parameters and annotated with #Field.
Can I use same "User" class for both ?
Yes , you can use the same Model as #Body for both requests !
Just make sure where you don't need the required variables just omit them !!
Remove the #SerializedName and #Expose , these are not required and give the variable names according to the json KEYs
public class User {
private Integer id;
private String email;
private String firstName;
private String lastName;
private String password;
}
Edit
Suppose for example , for one request you need :-
4 params you set the model user as
new User(id,email,firstname,lastname); // dont init the password attribute
5 params you set all values to the model like
new User(id,email,firstname,lastname,password);

Android retrofit missing fields in the POJO

I am using Retrofit to get the data from the API and parse it into a POJO object.
However, the API is not documented and I am not very sure what data does the JSON contain.
I have field in my POJO for the data I am sure is coming, but at times they are fields in the JSON that I have not accounted for.
Obviously, Retrofit just ignores these fields.
How can I make it send a warning when a field in the JSON is NOT in the POJO?
class User {
#SerializedName("id")
private Integer id;
#SerializedName("name")
private String name;
[relevant getters and setters]
}
The JSON that is coming is:
{
id: 5,
name: "John",
age: 23
}
Age field is not in the POJO, but at application does not throw any error; how do I make it display an error in such instances?
You may consider using Jackson to deserialize your POJO.
Then you can use the following annotations:
#JsonIgnoreProperties(ignoreUnknown = false)

How can i POST json data in Android

In my application I want POST some data, and this data get users and POST to server. For server requests I use Retrofit2.
For POST this data I should POST with json format, such as this :
{
"email": "example#example.com",
"username": "example",
"password": "123",
}
After POST data I should check with this results for submit data has Ok ro Not.
{
"status": 200,
"Message": "",
"data": true
}
I give Email, Username and Password with EditText from users, but how can I POST this data to server with Json format?
Please help me, I am amateur and I really need this help
Firstly, create a class for your request, for example, LoginRequest.java
public class LoginRequest {
private String email;
private String username;
private String password;
//getters and setters
}
Secondly, create a class for your response, LoginResponse.java
public class LoginResponse {
private Integer status;
private String Message;
private Boolean data;
//getters and setters
}
Finally, in your interface add this method:
public interface MiApiInterface {
#POST("yourResourceName") Call<LoginResponse> login(#Body LoginRequest request);
}
I hope It could help you, just ask me if you have more question.
have you realised that the return of the login method is a Call, it is for a async call, you could use it like this on your activity:
firstly, create a retrofit instance
Retrofit retrofit = ....
Secondly, create your interface instance like this:
MiApiInterface apiInterface = retrofit.create(MiApiInterface.class);
Finally, you could access the login method:
LoginRequest request = new LoginRequest();
request.set();
....
Call<LoginResponse> responseCall = apiInterface.login(request);
responseCall.enqueue(new Callback<LoginResponse>() {
public void onResponse(...){
LoginResponse loginResponse = response.body();
}
public void onFailure(...){
}
}
To Convert Objects to Json automatically, you should add a Converter Factory on your retrofit builder:
Gson gson = new GsonBuilder().create();
Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson))
...
dont forget import the Gson library on your gradle.
Here is a tutorial on Retrofit 2: http://www.vogella.com/tutorials/Retrofit/article.html
Alternatively, you can use Volley, it is a library specificaly designed to make http requests on Android. https://developer.android.com/training/volley/index.html

robospice parse nested object response

I have a JSON object returned by the server like:
{
"success":true,
"value1":1,
"otherValues":{
"var1":1,
"var2":"asd",
"var3":2
}
}
How should I model the response class to accept all the values? For example
package com.phoneme.API.popIndex;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class GetResponse {
private String success
private String value1;
private ??? otherValues;
//GETTERS AND SETTERS of each
}
The response you are trying to decode is not valid JSON. The field names need to be quoted. For example:-
{
"success":true,
"value1":1,
"otherValues":{
"var1":1,
"var2":"asd",
"var3":2
}
}
Using this corrected version of the message, you can generate your POJO here:- http://www.jsonschema2pojo.org/
Good luck!

GSON Deserializing Array of Custom Objects

I am trying to serialize/deserialize JSON in Android using GSON. I have two classes that look like this:
public class Session {
#SerializedName("name")
private String _name;
#SerializedName("users")
private ArrayList<User> _users = new ArrayList<User>();
}
and:
public class User {
#SerializedName("name")
private String _name;
#SerializedName("role")
private int _role;
}
I am using GSON for serializing/deserializing the data. I serialize like so:
Gson gson = new Gson();
String sessionJson = gson.toJson(session);
This will produce JSON that looks like this:
{
"name":"hi",
"users":
[{"name":"John","role":2}]
}
And I deserialize like so:
Gson gson = new Gson();
Session session = gson.fromJson(jsonString, Session.class);
I'm getting an error when I make this call.
DEBUG/dalvikvm(739): wrong object type: Ljava/util/LinkedList; Ljava/util/ArrayList;
WARN/System.err(739): java.lang.IllegalArgumentException: invalid value for field
I don't know what this error means. I don't see myself doing anything gravely wrong. Any help? Thanks!
Change your code to this:
public class Session {
#SerializedName("name")
private String _name;
#SerializedName("users")
private List<User> _users = new ArrayList<User>();
}
It's a good practice use Interfaces, and GSON requires that (at least, without extra configuration).
Gson converts the array "[ ]" in javascript, to a LinkedList object.
In your code, GSON tries to inject a LinkedList in the _users field, thinking than that field its a List.

Categories

Resources