Search code examples
androidretrofitretrofit2okhttp

Getting error code 400 bad request in retrofit but works on Postman


I'm working on an Registraion API which takes the JSON input as follow / request parameters:

{"httpMethod":"POST",
"firstname":"Ali",
"lastname":"Patel",
"email":"alipatel05@gmail.com",
"password":"12345678",
"country":"Canada",
"state":"Quebec",
"city":"Montreal",
"type":"Parent"}

but when I call the API from Android app it gives me bad response with error code 400 but works pretty fine on Postman.

My API Client

public class APIClient {
    private static Retrofit retrofit = null;
    public static final String BASE_URL = "https://5r8ndtx9zc.execute-api.us-east-2.amazonaws.com/";

    public static Retrofit getClient() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

        /*Gson gson = new GsonBuilder()
                .setLenient()
                .create();*/

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        return retrofit;
    }
}

My API interface

public interface APIInterface {

    @Headers({
            "Content-Type: application/json;charset=utf-8",
            "Accept: application/json;charset=utf-8",
            "Cache-Control: no-cache"
    })
    @POST("vaccinesApi")
    Call<ResponseBody> registerUser(@Body JSONObject locationPost);

}

and here's my API call:

private void registerUser() {

        HashMap<String, String> newhashMap = new HashMap<>();
        JSONObject hashMap = new JSONObject();
        try {
            hashMap.put("httpMethod","POST");
            hashMap.put("firstname",mEditFirstName.getText().toString().trim());
            hashMap.put("lastname",mEditLastName.getText().toString().trim());
            hashMap.put("email",mEditEmail.getText().toString().trim());
            hashMap.put("password",mEditPassword.getText().toString().trim());
            hashMap.put("country","Canada");
            hashMap.put("state","Quebec");
            hashMap.put("city",mSelectedCity);
            hashMap.put("type",mUserType);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Call<ResponseBody> call = apiInterface.registerUser(hashMap);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                progressDialog.hide();
                try {
                    JSONObject jsonObject = new JSONObject(response.body().toString());
                    Log.e("SignupFragment", jsonObject.toString());
                    if (response.code() == 200) {
                        Toast.makeText(RegistrationActivity.this, "Success",Toast.LENGTH_SHORT).show();
                    /*Intent intent = new Intent(RegistrationActivity.this, LoginActivity.class);
                    startActivity(intent);
                    finishAffinity();*/
                    } else {
                        Toast.makeText(RegistrationActivity.this, "Failed",Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                progressDialog.hide();
                call.cancel();
                Toast.makeText(RegistrationActivity.this, "Failed",Toast.LENGTH_SHORT).show();
            }
        });
    }

Should I need to changes my interface or there may be some error in my API call?


Solution

  • The issue is with your locationPost type, it should be JsonObject and not JSONObject, so try one of the following approaches

    Approach 1

    Api Interface

    Call<ResponseBody> registerUser(@Body JsonObject locationPost);
    

    Api call

    JsonObject obj = new JsonObject();
    obj.addProperty("httpMethod","POST");
    obj.addProperty("firstname",firstNameValue);
    
    // add the rest of the field
    
    Call<ResponseBody> call = apiInterface.registerUser(obj);
    
    //rest of the logic remains same
    

    Approach 2

    create a POJO class representing the object and pass the instance of the object

    public class RequestObject{
    
    final String  httpMethod, firstname;
    // declare member variables for all the keys
    
       RequestObject(String method,String firstname){
            this.httpMethod = method;
            this.firstname = firstname;
       }
    }
    

    API Interface

    Call<ResponseBody> registerUser(@Body RequestObject locationPost);
    

    Api call

    RequestObject requestobject = new RequestObject("POST","firstName");
    // add the rest of the field
    
    Call<ResponseBody> call = apiInterface.registerUser(requestObject);
    
    //rest of the logic remains same