Using Response Interceptors with Retrofit - android

I see that ResponseInterceptors are present in OkHttp. I would like to use one, but I'm using Retrofit rather than OkHttp directly.
My question is firstly is it possible to use ResponseInterceptors with retrofit? If so how? There's api methods for Request interceptors but I can't find any corresponding Response methods.

For anyone who stumbles across this, I managed to find the answer after further searching. Note that the below requires OkHttp 2.2+ and retrofit 1.9+
//First create the OkHttp client and add your response interceptor
OkHttpClient httpClient = new OkHttpClient();
httpClient.interceptors().add(new ApiResponseInterceptor());
//then set the client on your RestAdapter
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(ACCOUNTS_SERVICE_BASE_URL)
.setClient(new OkClient(httpClient))
.setConverter(new GsonConverter(gson))
.setRequestInterceptor(getAuthRequestInterceptor())
.setLogLevel(RestAdapter.LogLevel.FULL);

See also this this question, which appears to be a duplicate of this one. One possibility is to override the execute method in Retrofit's OkClient:
OkClient client = new OkClient(okHttpClient) {
#Override
public retrofit.client.Response execute(retrofit.client.Request request) throws IOException {
retrofit.client.Response response = super.execute(request);
// Inspect 'response' before returning it
return response;
}
};
RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
.setEndpoint(API_BASE_URL)
.setClient(client);

Related

How to get intermediate response from Retrofit API call?

I using Retrofit to making API call. All API call is working fine except one where its returning huge response around 15k records.
Issue is when made call progress bar is being shown infinitely until I get response. And as response too huge getting OOM exception.
As an solution I found that need to use #Streaming annotation. I used that but didn't get intermediate callback. I want API should return chunk of response one by one.
Please help me.
public static ServiceInterface getServiceAPIClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
Gson gson = new GsonBuilder()
.setLenient()
.create();
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(
new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
builder = request.newBuilder();
if (!TextUtils.isEmpty(PrefsHelper.getAccessTokenEdrm())) {
builder.addHeader(AUTHORIZATION, PrefsHelper.getAccessTokenEdrm());
}
builder.addHeader(API_VERSION, "1.0")
.addHeader("Accept", "application/json");
request = builder.build();
return chain.proceed(request);
}
}).connectTimeout(5, TimeUnit.MINUTES) .readTimeout(5, TimeUnit.MINUTES).addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
return retrofit.create(ServiceInterface.class);
}
API Method
#POST(EdrmConstants.SEARCH_DOCUMENTS)
#Streaming
Observable<ResponseBody> searchDocuments(#Body DocumentRequest documentRequest);
15k records is too match.
Retrofit needs time to make http request and makes serialization to your ResponseBody.class
I sure serialization takes main time.
I guess most right solution is to edit request on server side to split data on pages with 200-500 records.

Android Retrofit Interceptor add body param for all calls

Is there any way to edit the body of a network call for adding a default attribute used in the 95% of the calls?
I've seen that a query parameter is pretty easy to add (link)
But, I have not seen it for a Body.
My problem is that I'm working with an old API that asks me to send in each request the token. So I need to add this line in most of the classes.
#SerializedName("token") val token: String
Any ideas?
You should use httpInterceptor to solve this problem if you send in header
final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
// add token key on request header
// key will be using access token
.addHeader("token", yourToken)
.build();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
Edit : Im sorry, I've realized now you ask about sending in body.
I think it can be possible with old way(without Gson, Moshi etc). It is really more annoying than adding to every request.

How to use Okhttpclient Create a Http Delete Or Put Method With Params? android okhttpclient

Does anyone know in Android How to use Okhttpclient Create a Http Delete Or Put Method With Params?
Using java , this is what i have tried:
CookieJarImpl cookieJar = new CookieJarImpl(new PersistentCookieStore(context));
okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.addInterceptor(new LoggerInterceptor("TAG"))
.connectTimeout(10000L, TimeUnit.MILLISECONDS)
.readTimeout(10000L, TimeUnit.MILLISECONDS) //其他配置
.build();
You can build a URL with query parameters using the HttpUrl class. Then you can use an okhttp3.Request.Buidler() along with either the post() or delete() methods:
HttpUrl url = new HttpUrl.Builder()
.host(host).addQueryParameter(name, value).build();
Request request = new Request.Builder()
.url(url).post(RequestBody.create(mediaType, body)).addHeader(type, header).build();
okhttpClient.newCall(request).enqueue(new Callback() {
...
});
You can check out the OkHttp wiki for recipes if you need further help. Or you could use Square's other wonderful library, Retrofit, which pairs well with OkHttp.

Add Response call back when using retrofit with rxjava

I am using retrofit with Rxjava to get response from API as you can see the method i am using i can't see what's coming in the response and offcourse i don't need to becuase i am providing GsonConverter to retrofit but for some debugging reason i need to see the response that coming from API. How can i do this, what code i need to add.
public interface ProductApiService
{
String END_POINT = "http://beta.site.com/index.php/restmob/";
#GET(Url.URL_PRODUCT_API)
Observable<Product> getProducts(#Query("some_id") String cid);
class Creator
{
public static ProductApiService getProductAPIService() {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ProductApiService.END_POINT)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit.create(ProductApiService.class);
}
}
}
You can only do this as of Retrofit 2: Change the return type to include Response:
#GET(Url.URL_PRODUCT_API)
Observable<Response<Product>> getProducts(/* ...etc... */);
You can also use Observable<Result<Product>> if you want to see all possible errors in onNext (including IOException, which normally uses onError).
Daniel Lew's approach is quick and contains the least amount of boiler plate code. However, this may force you to refactor your networking logic. Since you mention needing this for debugging purposes, perhaps using a configured OkHttpClient with Interceptors is a less intrusive strategy.
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request req = chain.request();
Response resp = chain.proceed(req);
// ... do something with response
return resp;
}
})
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(httpClient)
.baseUrl(ProductApiService.END_POINT)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();

Retrofit intercept response

I have the following code for a ws request :
RestAdapter mRestAdapter = new RestAdapter.Builder()
.setEndpoint(ROOT_HOME_URL)
.setRequestInterceptor(mRequestInterceptor)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
mInterfaceWs = mRestAdapter.create(InterfaceWs.class);
How can i intercept the response before it arrives in my model ? I wana replace some keys strings inside the response.
Inside my response i have some keys named : .type and #text and inside my model i can not set those names as fields
What can i do ? Please help me
compile 'com.squareup.retrofit:retrofit:1.7.0'
RequestInterceptor mRequestInterceptor = new RequestInterceptor()
{
#Override
public void intercept(RequestFacade request)
{
request.addHeader("Accept","application/json");
}
};
So... i managed to solve my problem without any intercetor.
For those who will have the same problem as i did :
public class Atribute
{
#SerializedName(".type")
public String type;
#SerializedName("#text")
public String text;
public String getType() { return type; }
public String getText() { return text; }
}
You can use OKHttp Network Interceptors to intercept the response and modify it. For this you would need to setup a custom OkHTTP client to use with retrofit.
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new Interceptor() {
#Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
com.squareup.okhttp.Response response = chain.proceed(chain.request());
//GET The response body and modify it before returning
return response;
}
});
Then set it up to use with retrofit.
RestAdapter mRestAdapter = new RestAdapter.Builder()
.setClient(new OkClient(client))
.setEndpoint(ROOT_HOME_URL)
.setRequestInterceptor(mRequestInterceptor)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
You can read up more about network interceptors here
P.S: The link is for the latest version of OkHttp. The way you initialise network interceptors have changed in the latest version of OkHttp but the concept is the same. The code I gave should work with your old version (retrofit 1.7.0)

Categories

Resources