1

I have a strict API that will give me different JSON depending if the request is correct or not. I can have 2 differents JSON for one same request. The status of the request will ALWAYS be 200 (if it's an error or a success) so I cannot use the status of the request

Error response : 
{
    "stError": {
        "azType": "Application",
        "azCode": "Bad value parameter - azPassword is empty"
    }
}

Success response : 
{
     "azToken": "qsdsqd",   #1 And this field can be inexistant if the bLogin is 0
     "bLogin" : 1
}

So I created the POJO that I needed :

public class LoginAPIResponse {

    @SerializedName("azToken")
    @Expose
    private String azToken;
    @SerializedName("bLogin")
    @Expose
    private Boolean bLogin;

    ### Setters and getters stuff ###
}

public class LOLError {

    @SerializedName("stError")
    @Expose
    private stError stError;

    ### Setters and getters stuff ###
}

public class stError {

    @SerializedName("azType")
    @Expose
    private String azType;
    @SerializedName("azCode")
    @Expose
    private String azCode;

    ### Setters and getters stuff ###
}

And of course I have my service that I need when I create my webService

public interface LoginService {

    /***
     * @POST declares an HTTP POST Request
     * This request is use when a user needs to login with his credentials
     */
    @POST("JCExecDev/JCOSSUserLogin")
    Call<LOLError> login(@Body LoginAPIRequest request);
}

And here is my login function in my repository :

Call</*[DynamicResponse?]*/> call = loginService.login(request);

call.enqueue(new Callback</*[DynamicResponse?]*/>() {
    @Override
    public void onResponse(Call</*[DynamicResponse?]*/> call, Response<LOLError> response) {

    call.enqueue(new Callback</*[DynamicResponse?]*/>() {
        @Override
        public void onResponse(Call</*[DynamicResponse?]*/> call, Response<LOLError> response) {
           // Manage to find the way to get either LOLError or LoginAPIResponse
        }

        @Override
        public void onFailure(Call</*[DynamicResponse?]*/> call, Throwable t) {
        #Failure from the server, we do not take this in consideration
}
});

I am using retrofit 2 with GSON Deserialisation.

And here is my questions :

  • Can I dynamically load the right response with only retrofit (or find a way to have it in a DynamicResponse as I put it in the exemple)?
  • If not, would it be better to manager it with a custom deserializer ?
  • If I am using a custom deserializer, is their a way to use it so it can always return me the error if there is some errors (Maybe with templates ?)
  • Is there an easy way to do this by getting the raw data in my response and then deserialize it by hand ?
  • Finally, how can I manage the fact that some fields from my response may be inexistant like the token when the credentials aren't correct. For exemple, for a success response, I can either avec [bLogin : 0] or [azToken: "myToken", bLogin : 1] depending if the password is correct.

I CAN'T change the procedures, that means that I can't change my response and add a common field to the error and the success.

Sacha.R
  • 394
  • 2
  • 17
  • In such cases, most of the times the success and error components are placed in the same response entity and you can serialize it with that response entity. – Coder Jan 23 '19 at 14:10
  • inally, how can I manage the fact that some fields from my response may be inexistant like the token when the credentials aren't correct --- Can you elaborate further on what you mean by this? – Coder Jan 23 '19 at 14:12
  • I did just edit my post and added more informations about the inexistant field. Moreover, I can't placed both my Error and Success response in one object, I don't have any hand on the API, so I have to adapt myself to the API – Sacha.R Jan 23 '19 at 14:18
  • Possible duplicate. https://stackoverflow.com/questions/24279245/how-to-handle-dynamic-json-in-retrofit , https://stackoverflow.com/questions/41856975/how-to-parse-dynamic-json-with-retrofit – nasch Jan 23 '19 at 16:42

0 Answers0