Retrofit2: Modifying Request Body in Okhttp Interceptor

Retrofit2: Modifying request body in OkHttp Interceptor

I using this to add post parameter to the existing ones.

 OkHttpClient client = new OkHttpClient.Builder()
.protocols(protocols)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
RequestBody formBody = new FormEncodingBuilder()
.add("email", "Jurassic@Park.com")
.add("tel", "90301171XX")
.build();
String postBodyString = Utils.bodyToString(request.body());
postBodyString += ((postBodyString.length() > 0) ? "&" : "") + Utils.bodyToString(formBody);
request = requestBuilder
.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString))
.build();
return chain.proceed(request);
}
})
.build();

public static String bodyToString(final RequestBody request){
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if(copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
}
catch (final IOException e) {
return "did not work";
}
}

OkHttp3:

RequestBody formBody = new FormBody.Builder()
.add("email", "Jurassic@Park.com")
.add("tel", "90301171XX")
.build();

Retrofit2: Modifying request body (Json) in OkHttp

In Retrofit2 you can pass header, query, body params via method params. All you need just specify annotations. Below is an example.


Java Example:

@POST("adduser")
Call<User> addUser(@Header("Authorization") String header, @Body User userModel);

Check this links for more examples.

Modifying POST request Body when using Retrofit/OkHttp

Currently there is no support for the use case I'm asking for so I created new issue about it for Retrofit, see Argument pre-processor, deserialized post-processor #816

Retrofit 2 appending post to requestbody in intercept

You can do it without creating additional class.

client.interceptors().add(new Interceptor() {
@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String parameter = "&" + name + "=" + value;
Request newRequest = interceptRequest(request, parameter)
return chain.proceed(newRequest);
}
});

This is simple method that create new request.

 public static Request interceptRequest(@NotNull Request request, @NotNull String parameter)
throws IOException {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

Sink sink = Okio.sink(baos);
BufferedSink bufferedSink = Okio.buffer(sink);

/**
* Write old params
* */
request.body().writeTo(bufferedSink);

/**
* write to buffer additional params
* */
bufferedSink.writeString(parameter, Charset.defaultCharset());

RequestBody newRequestBody = RequestBody.create(
request.body().contentType(),
bufferedSink.buffer().readUtf8()
);

return request.newBuilder().post(newRequestBody).build();
}

Also you can get it from Gist

How to change body in OkHttp Response?

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.

Modify response body retrofit 2.2 interceptor

It's easy. The code below uses Google Guava in order to decode Base64 character streams and Google Gson to deserialize JSON content.

Consider the following test service interface:

interface IService {

@GET("/")
Call<String> get();

}

Now you can implement your interceptor response input stream transformer base using the template method design pattern:

abstract class AbstractTransformingDecodingInterceptor
implements Interceptor {

protected abstract InputStream transformInputStream(InputStream inputStream)
throws IOException;

@Override
@SuppressWarnings("resource")
public final Response intercept(final Chain chain)
throws IOException {
final Request request = chain.request();
final Response response = chain.proceed(request);
final ResponseBody body = response.body();
return response.newBuilder()
.body(ResponseBody.create(
body.contentType(),
body.contentLength(),
Okio.buffer(Okio.source(transformInputStream(body.byteStream())))
))
.build();
}

}

This implementation should also detect content MIME types in order not to do wrong transformations, but you can implement it yourself easily. So here are also two transforming interceptors for both Base64 and GZip:

final class Base64DecodingInterceptor
extends AbstractTransformingDecodingInterceptor {

private static final Interceptor base64DecodingInterceptor = new Base64DecodingInterceptor();

private Base64DecodingInterceptor() {
}

static Interceptor getBase64DecodingInterceptor() {
return base64DecodingInterceptor;
}

@Override
protected InputStream transformInputStream(final InputStream inputStream) {
return BaseEncoding.base64().decodingStream(new InputStreamReader(inputStream));
}

}
final class GzipDecodingInterceptor
extends AbstractTransformingDecodingInterceptor {

private static final Interceptor gzipDecodingInterceptor = new GzipDecodingInterceptor();

private GzipDecodingInterceptor() {
}

static Interceptor getGzipDecodingInterceptor() {
return gzipDecodingInterceptor;
}

@Override
protected InputStream transformInputStream(final InputStream inputStream)
throws IOException {
return new GZIPInputStream(inputStream);
}

}

And test it:

private static final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(getGzipDecodingInterceptor())
.addInterceptor(getBase64DecodingInterceptor())
.addInterceptor(getFakeContentInterceptor())
.build();

private static final Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://whatever")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();

private static final IService service = retrofit.create(IService.class);

public static void main(final String... args)
throws IOException {
final String body = service.get().execute().body();
System.out.println(body);
}

Note that getFakeContentInterceptor returns a fake interceptor that always returns H4sIAAAAAAAEACspKk0FAI1M/P0EAAAA so that baseUrl does not even have a real URL. The output:

true

Change Okhttp RequestBody form value

This question might have been replied to already. Please check the answer

The suggestion is to create a new FormBody and convert it to text, and concatenate with the existing form, also converted to text, then submit.



Related Topics



Leave a reply



Submit