58

I want to get the raw http response from my API REST. I have tried with this interface:

@POST("/login")
@FormUrlEncoded
Call<retrofit.Response> login(@Field("username") String login, @Field("password") String pass,
                     @Field("appName") String appName, @Field("appKey") String appKey);

But I get:

java.lang.IllegalArgumentException: Unable to create call adapter for retrofit.Call for method Api.login

I create Retrofit this way:

Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
retrofitBuilder.addConverterFactory(JacksonConverterFactory.create());
Retrofit retrofitAdapter = retrofitBuilder.baseUrl(baseUrl).build();
return retrofitAdapter.create(apiClass);
Héctor
  • 19,875
  • 26
  • 98
  • 200

3 Answers3

94

To get access to the raw response, use ResponseBody from okhttp as your call type.

Call<ResponseBody> login(...)

In your callback, you can check the response code with the code method of the response. This applies to any retrofit 2 return type, because your callback always gets a Response parameterized with your actual return type. For asynchronous --

Call<ResponseBody> myCall = myApi.login(...)
myCall.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
        // access response code with response.code()
        // access string of the response with response.body().string()
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
});

for synchronous calls --

Response<ResponseBody> response = myCall.execute();
System.out.println("response code" + response.code());
iagreen
  • 28,652
  • 7
  • 71
  • 88
  • But this is the response body. What about if I want to check the http response code? – Héctor Oct 26 '15 at 14:53
  • 1
    You will always get a `Response` object from which you can check the http code. See updated answer. – iagreen Oct 26 '15 at 15:39
  • Thank you. Is there a way to get the response object making request asynchronous? – Héctor Oct 26 '15 at 15:41
  • Yes, sync vs async is no longer encoded in the interface. You can decide on a per call basis. `enqueue` as used above is asynchronous. If you want it synchronous, you'd use `execute` with no callback -- Response myResponse = myCall.execute(); – iagreen Oct 26 '15 at 15:46
  • But I can't obtain the http response code from ResponseBody – Héctor Oct 26 '15 at 16:33
  • You get the `Response` which has the http code. How is it failing to get the code? – iagreen Oct 26 '15 at 17:20
  • I get the Response in the asynchronous way, but not in the synchronous one. Maybe, I'm confused – Héctor Oct 26 '15 at 17:28
  • synchronous case is easier -- added an example above. If you are not seeing the print statement execute check to see if there is an exception thrown – iagreen Oct 26 '15 at 17:36
  • @iagreen How will I fetch JSON response from ResponseBody? – user1288005 Mar 11 '16 at 07:15
  • 1
    response.body().string(): Cannot resolve method string – Kairat Doshekenov May 26 '18 at 07:21
  • This doesn't really answer the question though... OP asked how to get it with Retrofit, not OkHttp. – reka18 Mar 24 '19 at 17:19
  • For anyone who doesn't want to change a lot of code and just want to log responses for some testing purpose, the answer by Rob Anderson below is the way to go. – Bugs Happen Apr 27 '20 at 07:30
37

You can get information about headers, response code, down to raw json response body by using Interceptors. You can write your custom Interceptors but I prefer to use Square's own Logging Interceptor. It's available on maven central.

compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'

Here's how to use it

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

Logging level BODY will print headers to the body response. And in your Retrofit

Retrofit retrofit = new Retrofit.Builder()
            .client(client)               
            .baseUrl("https://yourapi.com/api/")
            .build();

Now, open up Log Cat and you'll see raw HTTP response.

Caution!

Don't forget to remove Interceptors (or change Logging Level to NONE) in production! Otherwise people will be able to see your request and response on Log Cat.

aldok
  • 13,524
  • 4
  • 47
  • 61
4

I had the same problem but a different solution. I took the request and send it with OkHttp3Client. Like this:

//raw text 
Request request = call.clone().request();
OkHttpClient client = new OkHttpClient();
okhttp3.Response test = client.newCall(request).execute();
System.out.println(test.body().string());

source: http://robinhenniges.com/de/retrofit-2-raw-response

Rob Anderson
  • 2,247
  • 3
  • 17
  • 31