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
Android 4.4 Giving Err_Cache_Miss Error in Onreceivederror for Webview Back
Using an Android Library Project Activity Within Another Project
Mediametadataretriever.Getframeattime() Returns Only First Frame
Android:Load Svg File from Web and Show It on Image View
How to Test Boot_Completed Broadcast Receiver in Emulator
How to Move an Image from Left to Right in Android
How to Search for a Value in Firebase Android
Creating a Dialogpreference from Xml
Cardview Inside Recyclerview Has Extra Margins
Can't Handle Both Click and Touch Events Simultaneously
Android Emulator - Trouble Creating User Accounts
Okhttp Library - Networkonmainthreadexception on Simple Post
Android - How to Intercept the 'Install Application' Intent
Noclassdeffounderror Below Sdk 21
How to Have 1 Firebase Database for 2 Apps with Different Package Names
Having Issue on Real Device Using Vector Image in Android. Svg-Android