I am using an Retrofit with an Okhttp interceptor in order to detect if my oauth token has expired. If the token has expired, I want to request a new token, try the request again, then send that response to Retrofit.
Here is my interceptor class:
public class CustomInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// try the request
Response response = chain.proceed(request);
if (response.body().string().contains(Constants.TOKEN_AUTH_ERROR_MESSAGE)) {
Log.v("retrofit_error", "token expired");
//get current token, create headers
OAuthTokenResponse expiredToken = SharedPreferencesUtil.getOAuthToken();
OAuthTokenResponse newOauthToken = RestClient.getInstance().getTokenService().refreshOauthToken(expiredToken.getRefreshToken());
//store new token, return
SharedPreferencesUtil.saveOAuthToken(newOauthToken);
// create a new request and modify it accordingly using the new token
Request.Builder newRequestBuilder = request.newBuilder()
.removeHeader("Authorization");
Request newRequest = newRequestBuilder.addHeader("Authorization", SharedPreferencesUtil.getOAuthToken().getAccessToken()).build();
// retry the request
return chain.proceed(newRequest);
}
// otherwise just pass the original response on
return response;
}
}
The issue is that calling response.body.string() will consume the ResponseBody due to it being a one-shot value as the Okhttp docs state.
This means that the Response returned at the end of the code will no longer container the body when it is passed off to retrofit. Is there any way that I can consume the body while still returning it with the response?
Thanks!
I accomplished this by creating a new response using the Response.Builder. I am able to use responseBodyString
for my checks; then I return newResponse
, which is given the body that I consumed.
Request request = chain.request();
Response response = chain.proceed(request);
ResponseBody responseBody = response.body();
String responseBodyString = response.body().string();
Response newResponse = response.newBuilder().body(ResponseBody.create(responseBody.contentType(), responseBodyString.getBytes())).build();
...
return newResponse;
you can use Logging Interceptor https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With