It is possible with custom json deserializer. You only have user when the status is success in case it is not you have the reason. In case you have status error and try to access user its null.
public class CustomConvertor implements JsonDeserializer<Response> {
@Override
public Response deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Gson gson = new Gson();
Response response = gson.fromJson(json, Response.class);
if (response.getStatus().equals("success")) {
// The full response as a json object
final JsonObject jsonObject = json.getAsJsonObject();
// The user attribute in the JSON received
final JsonElement jsonElement = jsonObject.get("user");
User user = gson.fromJson(jsonElement, User.class);
response.setUser(user);
}else{
// you could do this
// not needed as json is deserialized to Response already
// just for the example
final JsonObject jsonObject = json.getAsJsonObject();
String reason = jsonObject.getAsJsonPrimitive("reason").getAsString();
response.setReason(reason);
}
return response;
}
}
The retrofit part
GsonBuilder gsonBuilder =new GsonBuilder();
gsonBuilder.registerTypeAdapter(Response.class, new CustomConvertor());
Gson gson = gsonBuilder.create();
GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(gson);
Retrofit retrofit = new Retrofit.Builder()
...// other setups
.addConverterFactory(gsonConverterFactory).build();
Then
// service is my case
Service service = retrofit.create(Service.class);
// call enqueue in your case.for testing i used mockwebserver
Response response = service.exampleJson().execute().body();
Log.i("User: ","" + response.geUser().getFullname());
in case of error
Log.i("Error: ","" + response.getReason());
You can get your pojos from http://www.jsonschema2pojo.org/
Pojo's
Response.java
public class Response {
@SerializedName("status")
@Expose
private String status;
@SerializedName("user")
@Expose
private User user;
@Expose
@SerializedName("reason")
private String reason;
public void setReason(String reason) {
this.reason = reason;
}
public String getReason() {
return reason;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
User.java
public class User {
@SerializedName("user_id")
@Expose
private int userId;
@SerializedName("full_name")
@Expose
private String fullName;
@SerializedName("email_address")
@Expose
private String emailAddress;
@SerializedName("end_date")
@Expose
private Object endDate;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public Object getEndDate() {
return endDate;
}
public void setEndDate(Object endDate) {
this.endDate = endDate;
}
}
The other way
Call<Response> auth = .// setup
auth.enqueue(new Callback<Response>() {
@Override
public void onResponse(Call<Response> call, Response<Response> response) {
if (response.isSuccessful() ) {
Response respojo = response.body();
if(respojo.getStatus().equals("success"){
Log.i("User: ","" + respojo.getUser().getFullname());
}else {
Log.i("Error: ","" + respojo.getReason());
}
}
} else {
response.errorBody();
}
}
@Override
public void onFailure(Call<Response> call, Throwable t) {
t.printStackTrace();
}
});