I have an OkHttpInterceptor which intercepts every request made by the App to append an token in the request header.
private OkHttpClient getOKHttpClient() {
return new OkHttpClient().newBuilder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder().header("x-access-token", getNewTokenPassively());
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
}).build();
}
I am using this method add an interceptor
....
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(getOKHttpClient())
.build();
....
This is not working in SDK 25 and above where, any http call call.enqueue methods does not work and API call never goes through...
if I replace .client(getOKHttpClient()) with .client(newOkHttpClient.Builder().build()) everything works fine.
Am I missing something obvious here?
Related
I have query parameters that is used for all requests. It is added to the base url as follow
private val baseUrl = HttpUrl.Builder()
.scheme("http")
.host("ws.audioscrobbler.com")
.addPathSegment("2.0")
.addPathSegment("")
.addQueryParameter("format", "json")
.addQueryParameter("api_key", "val")
.build()
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
The api service call is
#GET("./")
fun searchTracks(#Query("otherParam") query: String): Call<Any>
The url is built correctly till the actual call is made. It removes the query params added in the base url and keeps only the one added in service call.
Shown in debugging till the delegate.enqueue() is called in ExecutorCallAdapterFactory:"http://ws.audioscrobbler.com/2.0/?format=json&api_key=val&otherParam=val"
shown in logs (via interceptor): "http://ws.audioscrobbler.com/2.0/?otherParam=val"
Any idea why this happens and how to keep the parameters?
You should add query parameters to url in request interceptor.
OkHttpClient.Builder httpClient =
new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
HttpUrl originalHttpUrl = original.url();
HttpUrl url = originalHttpUrl.newBuilder()
.addQueryParameter("format", "json")
.addQueryParameter("api_key", "val")
.build();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.url(url);
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
I have a strange problem with one of my retrofit call,it works fine when the app is in the background(recent list)
I have a call through which i update my widget data,the problem is when the app is cleared of from the recent list,the call gives HTTP 401 unauthorized response.
however i pass the same bearer token with it.
please have a look at the code and suggest some help
public static OkHttpClient getOkhttpClient() {
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + TokenGenerator.getToken())
.build();
return chain.proceed(newRequest);
}
}).build();
return client;
}
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getOkhttpClient())
.addConverterFactory(JacksonConverterFactory.create())
.build();
}
return retrofit;
}
I am creating an application with retrofit2 for network calls. I need call multiple API in Single Activity. Now I am facing the 403-forbidden error. If I call only one API it is working fine. But if I use multiple API calls one by one then I am facing this error.
My CreateService method is below:
public static <S> S createService(Class<S> serviceClass, final String authToken) {
if (authToken != null) {
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Authorization-Token", authToken)
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
}
// OkHttpClient client = httpClient.readTimeout(60, TimeUnit.SECONDS).connectTimeout(60, TimeUnit.SECONDS).build();
Dispatcher dispatcher = new Dispatcher(Executors.newFixedThreadPool(200));
dispatcher.setMaxRequests(200);
dispatcher.setMaxRequestsPerHost(1);
OkHttpClient okHttpClient = httpClient.dispatcher(dispatcher).connectionPool(new ConnectionPool(100, 30, TimeUnit.SECONDS)).build();
Retrofit retrofit = builder.client(okHttpClient).build();
return retrofit.create(serviceClass);
}
What is wrong in my code.. How can I handle this?
Are you sure that string is not empty string?
Could you please add log interceptor and set the log level and provide a log?
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
And sth like this :
OkHttpClient.Builder okBuilder = new OkHttpClient.Builder();
okBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC).setLevel
(HttpLoggingInterceptor.Level.BODY).setLevel(HttpLoggingInterceptor.Level.HEADERS))
Now i need to get thing shadow from aws-iot api.so when i hit same request into postman got 200ok in response.
From the app-side i got 403 i.e.forbidden.
Here i used "okhttp client" for fetch the request.
also attached image where i got 200ok response.
Now what i do from app side?I think its permission issue but not able to resolved please suggest.
also attached code as follows:-
Interceptor interceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request newRequest = chain.request()
.newBuilder()
.addHeader("content-type", "application/x-www-form-urlencoded")
.addHeader("host", "ag7fce49bf5ti.iot.us-east-1.amazonaws.com")
.addHeader("x-amz-date", "20160919T054450Z")
.addHeader("authorization", "AWS4-HMAC-SHA256 Credential=AKIAJ6XB3CLURFLV6ISQ/20160919/us-east-1/iotdata/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=af7cd8cee7dd4763cff3a1c8f91cdde1fa22cc68012248a694cee098981bc623")
.build();
return chain.proceed(newRequest);
}
};
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(interceptor);
client = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://ag7fce49bf5ti.iot.us-east-1.amazonaws.com/things/dm_project/shadow/")
//.addConverterFactory(client)
.client(client)
.build();
im trying to consume an api that has that authorization header, i can get a 200 response in Postman with all data but cant get it to work in retrofit
May be you need add the Token using OkHttp Interceptor.
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(mTokenInterceptor)
.build();
then add it to Retrofit:
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(base_url)
.build();
the mTokenInterceptor:
Interceptor mTokenInterceptor = new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (mToken != null) {
Request.Builder requestBuilder = request.newBuilder()
.addHeader("Authorization", mToken);
Request newRequest = requestBuilder.build();
return chain.proceed(newRequest);
}
return chain.proceed(request);
}
};
when you get the Token, just assign the mToken,
You can try something like below, just a crude example
#GET("your server url goes here")
Call<Your_Model_Class> getServerData(#Header("Authorization") String token);
Pass your token to getServerData method.