Skip to content Skip to sidebar Skip to footer

Retrofit Gets 400 Bad Request But Works With Postman

My api base url is: https://locodealapi.herokuapp.com/api/deals In postman pass following in header and it works fine. x-access-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX

Solution 1:

1.Frist thing your api is a GET Method so use @GET instead @POST

Second try to change url base url in retrofit .baseUrl("https://locodealapi.herokuapp.com") to .baseUrl("https://locodealapi.herokuapp.com/") this will work. or leave your problem in comment 2.this is sample code

HttpLoggingInterceptorinterceptor=newHttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClientokHttpClient=newOkHttpClient.Builder().addInterceptor(
            newInterceptor() {
                @Overridepublic Response intercept(Chain chain)throws IOException{
                 Requestoriginal= chain.request();
                    // Request customization: add request headers
                    Request.BuilderrequestBuilder=original.newBuilder().
                            method(original.method(), original.body());
                    Requestrequest= requestBuilder.build();
                    return chain.proceed(request);
                }
            })
            .addInterceptor(interceptor).connectTimeout(60,TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();

    Retrofitretrofit=newRetrofit.Builder().baseUrl("https://locodealapi.herokuapp.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient).build();
    UserApiuserApi= retrofit.create(UserApi.class);
    Call<ResponseBody> call = userApi.deals("your token");
    call.enqueue(newCallback<ResponseBody>() {
        @OverridepublicvoidonResponse(Call<ResponseBody> call,retrofit2.Response<ResponseBody> response) {
        }
        @OverridepublicvoidonFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

@GET("api/deals") Call deals(@Header("x-access-token") String x_access_token);

Solution 2:

Greeting of the day!

Try this:

@FormUrlEncoded@POST("/api/deals")
    Call<ResponseBody> deals(@Header("x-access-token") String x_access_token, @Field("<parameter_name>") String parameter);

Call api as below:

Call<ResponseBody>call= client.deals(token,"<parameter>");

Here, i am assuming that the API has a parameter which can be passed as 2nd argument in the method deals(). You can pass multiple parameters as the arguments of the method.

Refer the following link for more details: https://futurestud.io/tutorials/retrofit-send-data-form-urlencoded

I hope, this solves your problem. If not, please provide complete details of the API that you want to call.

Solution 3:

A 400 response means that it's a disagreement between your request and the server, but that the request was created, sent, and a response was parsed. Which means Retrofit is working fine. You can use OkHttp's logging interceptor to log the raw request and compare it with what the server expects.

Also your Response size is around 5.96 MB. This is too big response. Instead of receiving this much of data in single response you could implement pagination or something similar to break down data. This could be one of the reason.

Solution 4:

//Your Main connection ClasspublicclassApiClient {
publicstaticfinalintDEFAULT_TIMEOUT_SEC=90;
publicstatic OkHttpClient client;
privatestaticRetrofitretrofit=null;

publicstatic Retrofit getClient() {

    OkHttpClient.BuilderhttpClient=newOkHttpClient.Builder()
            .connectTimeout(DEFAULT_TIMEOUT_SEC, TimeUnit.SECONDS)
            .readTimeout(DEFAULT_TIMEOUT_SEC, TimeUnit.SECONDS)
            .writeTimeout(DEFAULT_TIMEOUT_SEC, TimeUnit.SECONDS);

    httpClient.addInterceptor(newInterceptor() {
        @Overridepublic Response intercept(Interceptor.Chain chain)throws IOException {
            Requestoriginal= chain.request();
            System.out.println("API_KEY"+PrefManager.getActiveInstance(RecrouteCandidateApplication.getsCurrentContext()).getDeviceToken());
            Requestrequest= original.newBuilder()
                    .header("x-access-token",YOUR_ACCESS_TOKEN"")
                    .method(original.method(), original.body())
                    .build();

            return chain.proceed(request);
        }
    });

   //For logging the call on LogcatHttpLoggingInterceptorinterceptor1=newHttpLoggingInterceptor();
    interceptor1.setLevel(HttpLoggingInterceptor.Level.BODY);
    httpClient.addInterceptor(interceptor1);
    client = httpClient.build();

    if (retrofit == null) {
        retrofit = newRetrofit.Builder()
                .baseUrl(AppConstants.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

Use in Your Class which will initiate the connection like this

ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

And This will be your ApiInterface

publicinterfaceApiInterface {

@POST("Your url here")
Call<JsonObject> sampleMethod();
/*For non-empty body use this*///Call<JsonObject> getSignUpResponse(@Body JsonObject register);//For form data use this@FormUrlEncoded@POST("Your url here")
Call<String> sampleMethod1(@Field(value= "param1_key", encoded = true) String param1_value);

 }

Make a call like this for json

JsonObject obj= new JsonObject();
obj.addProperty("key1","keyvalue");

Call<JsonObject> call = apiService.sample1(obj);
                            call.enqueue(new Callback<JsonObject>() {
                                @Override
                                publicvoidonResponse(Call<JsonObject> call, Response<JsonObject> response) {
                                    if (response.body().get("status").getAsString().equals("1")) {
                                        Toast.makeText(context, response.body().get("msg").getAsString(), Toast.LENGTH_LONG).show();
                                    } else {
                                        Toast.makeText(context, response.body().get("msg").getAsString(), Toast.LENGTH_LONG).show();
                                    }
                                }

                                @Override
                                publicvoidonFailure(Call<JsonObject> call, Throwable t) {
                                    Toast.makeText(context, AppConstants.NO_DATA_AVAILABLE, Toast.LENGTH_LONG).show();
                                }
                            });

Solution 5:

for me the problem was because I had this line in the Gson builder :

.excludeFieldsWithoutExposeAnnotation()

with the above line, all the fields in your model classes that you send as body in retrofit will be ignored if they are not annotated with the @Exposed annotation. removing .excludeFieldsWithoutExposeAnnotation() solved the problem for me.

Post a Comment for "Retrofit Gets 400 Bad Request But Works With Postman"