Reputation: 1238
I am using retrofit 2
as a REST client and I cannot figure out how to deserialise a dynamic JSON response
.
Depending on the status value (success or failure), our JSON can have two different objects in the result
field:
A successful response returns a User
object:
{
"status": 200,
"message": "OK",
"result": {
"id": "1",
"email": "[email protected]"
...
}
}
A failed response returns an Error
object:
{
"status": 100,
"message": "FAILED",
"result": {
"error": "a user with this account email address already exists"
}
}
I have created 3 POJO
classes...
APIResponse:
public class APIResponse<T> {
@Expose private int status;
@Expose private String message;
@Expose private T result;
...
}
User:
public class User {
@Expose private String id;
@Expose private String email;
...
}
Error:
public class Error {
@Expose private String error;
...
}
Here is how I make the call:
@FormUrlEncoded
@PUT(LOGIN)
Call<APIResponse<User>> login(@Field("email") String email, @Field("password") String password);
And here is how I get a response:
@Override
public void onResponse(Call<APIResponse<User>> call, Response<APIResponse<User>> response) {
...
}
@Override
public void onFailure(Call<APIResponse<User>> call, Throwable t) {
...
}
Question:
The API call
expects a return type of Call<APIReponse<User>>
. However, it might not get a User
object back... So how do I modify this approach to accept either APIResponse<User>
or APIResponse<Error>
.
In other words, how do I deserialise JSON data that can be in two different formats?
Solutions I have looked at:
Upvotes: 1
Views: 2252
Reputation: 2866
I am not sure if the solution is viable, but you can try changing <APIResponse<User>>
to <APIResponse<Object>>
Call<APIResponse<Object>> login(@Field("email") String email, @Field("password") String password);
@Override
public void onResponse(Call<APIResponse<Object>> call, Response<APIResponse<Object>> response) {
//depending on the response status, you can cast the object to appropriate class
Error e = (Error)response.body().getResult();
//or
User u = (User)response.body().getResult();
}
or another alternative, use String instead of POJO
Call<String> login(@Field("email") String email, @Field("password") String password);
retrieve the JSON and serialize manually or use GSON
Upvotes: 1
Reputation: 357
You should check the response code and use the desired class to process the json
Upvotes: 0