NickUnuchek
NickUnuchek

Reputation: 12857

How to change body in OkHttp Response?

I'm using retrofit. To catch response i'm using Interceptor:

OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(myinterceptor);

here is code of interceptor:

new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        if (path.equals("/user")){
            String stringJson = response.body().string();
            JSONObject jsonObject = new JSONObject(stringJson);
            jsonObject.put("key",1);
            //here I need to set this new json to response and then return this response

How to change body in OkHttp Response?

Upvotes: 28

Views: 37050

Answers (6)

Mostafa Arian Nejad
Mostafa Arian Nejad

Reputation: 1665

The create() function has been deprecated and replaced with .toResponseBody() and .asResponseBody() extensions.

OkHttpClient.Builder().apply {
    addInterceptor { chain ->
        // modifiedBodyString is created here ...

        val contentType = response.body().contentType();

        // Old approach (Deprecated):
        val responseBody = ResponseBody.create(contentType, modifiedBodyString);

        // New approach:
        val responseBody = modifiedBodyString.toResponseBody(contentType)

        response.newBuilder().body(responseBody).build(); 
    }
}.build()

I am using OkHttp version 4.10.0.

Upvotes: 0

JohnnyLambada
JohnnyLambada

Reputation: 12826

Here's a tight, complete example of adding an interceptor that modifies JSON to an OkHttpClient. It uses GSON to manage the JSON.

        client.addInterceptor(chain -> {
            final Request request = chain.request();
            final String path = request.url().uri().getPath();
            final Response response = chain.proceed(request);

            String body = response.body().string();
            final JsonElement element = new JsonParser().parse(body);
            if ("/the/endpoint/you/want/to/modify".equals(path)){
                final JsonObject object = element.getAsJsonObject();
                // v v v v v v All this for these lines v v v v v v v
                object.addProperty("some_json_name","some_json_value");
                object.addProperty("existing_property","updated_value");
                object.addProperty("numbers_work_too",1.2);
                // ^ ^ ^ ^ ^ ^ All this for these lines ^ ^ ^ ^ ^ ^ ^
                body = object.toString();
            }
            return response.newBuilder().body(ResponseBody.create(response.body().contentType(), body)).build();
        });

Upvotes: 3

Pong Petrung
Pong Petrung

Reputation: 1447

   JSONObject postdata = new JSONObject();
            try {

                postdata.put("citizenId", "2222222222222");
                postdata.put("accuracy", 3043.323);
                postdata.put("provider", "wifi");
                postdata.put("gpsTime", 1111111111111L);
                postdata.put("lat", 23434.564);
                postdata.put("lng", 34343.5445);
                postdata.put("appId", "201");

            } catch(JSONException e){
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            RequestBody body = RequestBody.create(MEDIA_TYPE,postdata.toString());

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

        //    final OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();


            final Request request = new Request.Builder()
                    .url(base_url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvd25lcklkIjoyLCJvd25lclR5cGUiOiJMRUFERVIiLCJpYXQiOjE1MDE4Mjc4MDMsImV4cCI6MzMwMzc4Mjc4MDMsImF1ZCI6InNlbmRpdC5hc2lhIiwiaXNzIjoic2VsZiJ9.3Gpn3beZfdYsMOLTjksLwmxyfbrfqiojdm1n-gh6CXY")
                    .addHeader("cache-control", "no-cache")
                    .build();


            client.newCall(request).enqueue(new Callback() {

                @SuppressLint("LongLogTag")
                @Override
                public void onResponse(Call call, Response response) throws IOException {

                    try {
    //                    response = client.newCall(request).execute();
    //                    Protocol protocol = response.protocol();
    //                    assertEquals(Protocol.HTTP_1_1, protocol);

    //                    BufferedSource source = response.body().source();
    //                    source.request(Long.MAX_VALUE); // Buffer the entire body.
    //                    Buffer buffer = source.buffer();
    //                    String responseBodyString = buffer.clone().readString(Charset.forName("UTF-8"));

                        if(response.code() == 200) {
                            JSONObject jsonObject = new JSONObject();
                            try {
                                jsonObject.put("code",200);
                                jsonObject.put("status","OK");
                                jsonObject.put("message","Successful");

                                MediaType contentType = response.body().contentType();
                                ResponseBody body = ResponseBody.create(contentType, jsonObject.toString());

                        BufferedSource source = response.body().source();
                        source.request(Long.MAX_VALUE); // Buffer the entire body.
                        Buffer buffer = source.buffer();
                        String responseBodyString = buffer.clone().readString(Charset.forName("UTF-8"));

                                Log.e("response body responseBodyString ", body.string());
                                Log.e("response body responseBodyString  ", responseBodyString);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }


                        Log.e("response", String.valueOf(response));
                        Log.e("response body", String.valueOf(response.body()));

                    } }catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e("response  onFailure ", String.valueOf(e));
                }

            });

Upvotes: 0

linakis
linakis

Reputation: 1231

As a minor change I wouldn't use the string() method cause it can be called only once on this request. You do use the response.newBuilder() so other interceptors down the chain will be able to call string() on your new one but I found myself wasting a couple of hours because I was actually calling it twice :P.

So i suggest something like the following

BufferedSource source = response.body().source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
String responseBodyString = buffer.clone().readString(Charset.forName("UTF-8"));

Upvotes: 10

Aniket
Aniket

Reputation: 201

Below is Response Intercepter class where you can intercept okkhttp responce and add your own response. and send it to retrofit.

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.ResponseBody;
import retrofit2.Response;

public class ApiResponseInterceptor implements Interceptor {

    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        okhttp3.Response response = chain.proceed(request);
        if(response.code() == 200) {
            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject.put("code",200);
                jsonObject.put("status","OK");
                jsonObject.put("message","Successful");

                MediaType contentType = response.body().contentType();
                ResponseBody body = ResponseBody.create(contentType, jsonObject.toString());
                return response.newBuilder().body(body).build();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else if(response.code() == 403) {

        }
        return response;
    }
}

Yow will get your modified response here in your retrofit callback

call.enqueue(new Callback<EventResponce>() {
            @Override
            public void onResponse(Call<EventResponce> call, Response<EventResponce> response) {
                // you will get your own modified responce here
            }

            @Override
            public void onFailure(Call<EventResponce> call, Throwable t) {

            }
        });

Upvotes: 18

Rohit5k2
Rohit5k2

Reputation: 18112

Add this

MediaType contentType = response.body().contentType();
ResponseBody body = ResponseBody.create(contentType, jsonObject);
return response.newBuilder().body(body).build();

after your response modification. jsonObject is the modified JSON you want to return.

Upvotes: 39

Related Questions