Retrofit android header User-Agent not showing on Log - android

i do an interceptor and set header User-Agent like this
public class UserAgentInterceptor implements Interceptor {
private final String userAgent;
public UserAgentInterceptor(String userAgent) {
this.userAgent = userAgent;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.header("User-Agent", userAgent)
.build();
return chain.proceed(requestWithUserAgent);
}
}
and i add log showen like this
private RestAdapter getRestAdapterFromUrl(String url)
{
OkHttpClient okHttp = new OkHttpClient();
okHttp.setConnectTimeout(18000, TimeUnit.MILLISECONDS);
okHttp.setReadTimeout(18000, TimeUnit.MILLISECONDS);
// On ajoute user agent intercepteur
okHttp.networkInterceptors().add(new UserAgentInterceptor(VersionUtil.getUserAgent()));
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(url)
.setClient(new RestoflashClientWrapper(new OkClient(okHttp)))
//.setConverter(new retrofit.converter.JacksonConverter(jsonMapperUnwrapped))
.setConverter(new JacksonConverter(jsonMapper,jsonMapperUnwrapped))
//.setRequestInterceptor(new RestoFlashRequest())
.setLogLevel(RestAdapter.LogLevel.FULL);
builder.setRequestInterceptor(interceptor);
builder.setLogLevel(RestAdapter.LogLevel.HEADERS_AND_ARGS).setLog(new AndroidLog("RETROFIT_LOG"));
return builder.build();
}
and also instead of RestAdapter.LogLevel.HEADERS_AND_ARGS . i tried RestAdapter.LogLevel.FULL but on the log i can' see the User-Agent header on the log of android studio ?
thanks you for helping

personally I had the same problem.
new OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
And i had to add an interceptor that explicitly log the headers.
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder();
/*log debug info*/
Request request = requestBuilder.build();
for (int i = 0; i < request.headers().size(); i++) {
Timber.tag("OkHttp").d(String.format("%s: %s", request.headers().name(i), request.headers().value(i)));
}
return chain.proceed(request);
}
And I also use a CurlInterceptor that allows to log a "curl", which is useful if you want to test quickly via tools such as "Postman".
CurlInterceptor sample here
Hoping to have answered your need!

Related

how to get bitmap from url with using authorization header?

I tried picasso and volley but it is very troublesome to get an image from url. How to add auth header with token to get bitmap in asynctask?
Just call it and then use the picasso instance, here I add an access token. But you could also add username and password.
private void setupPicasso()
{
final Context c = context;
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
String token = <token you got when you logged in>;
String authString = "Bearer "+token;
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", authString)
.build();
return chain.proceed(newRequest);
}
})
.build();
picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(client))
.build();
}

How to change activity while get 401 status code in Interceptor Android

When I am getting 401 status code in API then I have to open login activity. I don't want to put change activity logic in every API's onError method. I want a global method which used for all the API's.
So for that, I created one Interceptor
public class MyInterceptor extends BaseActivity implements Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (response.code() == 401) {
throw new RuntimeException(" Here you got 401 from API !");
}
return response;
}
}
Here I add this Interceptor
OkHttpClient.Builder builder=new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Content-Type", "application/json")
.addHeader("User-Agent", "MyApp-Android-App")
.build();
return chain.proceed(newRequest);
}
})
.addNetworkInterceptor(new StethoInterceptor())
.addNetworkInterceptor(new MyInterceptor())
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
Now, where should I add change activity call method. One more thing I am calling API using RxRetrofit. I want a global method for handling this 401 response. Can you please provide me any solution where should I put Activity change method call?
create interceptor class
class HeaderInterceptor implements Interceptor
{
#Override
public Response intercept(Chain chain) throws IOException {
Request orignal = chain.request();
///--------------------------
String token="your auth token"; //retriving depend upon you
//---------------------------
Request request =orignal.newBuilder().header("Authorization", "Bearer "+ token)
.header("Accept", "application/json")
.header("Content-Type", "application/json").
method(orignal.method(), orignal.body())
.build();
Response response = chain.proceed(request);
Log.d("MyApp", "Code : "+response.code());
if (response.code() == 401){
//handle it as per ur need
return response;
}
return response;
}
}
now add interceptor
.....
.addInterceptor(logging).addInterceptor(new HeaderInterceptor())
.build();
..

Android - Retrofit2 - 403-Forbidden

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))

how to access api with api_key Using Retrofit

I am new on android.Can any one tell me how to add the header for api_key using retrofit.I am not able to understand how i can do this.
I find this code from net.where i have to put this code in android folder structure.I am confused with this.where i have to add api_key.
// Define the interceptor, add authentication headers
Interceptor interceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder().addHeader("User-Agent", "Retrofit-Sample-App").build();
return chain.proceed(newRequest);
}
};
// Add the interceptor to OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(interceptor);
OkHttpClient client = builder.build();
// Set the custom client when building adapter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
You can store your api_key in your strings.xml file like this:
<string name="your_api_key_id" translatable="false">YOUR_API_KEY</string>
Then, in your OkHttpClient definition class, write a method to build your OkHttpClient like that:
private final static String API_KEY_IDENTIFIER = "key_identifier";
private OkHttpClient getHttpClient(){
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
HttpUrl originalUrl = original.url();
HttpUrl url = originalUrl.newBuilder()
.addQueryParameter(API_KEY_IDENTIFIER, mContext.getString(R.string.your_api_key_id))
.build();
Request.Builder requestBuilder = original.newBuilder().url(url);
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
return httpClient.build();
}
You should implement your client builder class with Singleton pattern, in order to have the client build centralized in one place inside your code

How to specify a default user agent for okhttp 2.x requests

I am using okhttp 2.0 in my Android app and didn't find a way to set some common User Agent for all outgoing requests.
I thought I could do something like
OkHttpClient client = new OkHttpClient();
client.setDefaultUserAgent(...)
...but there's no such method or similar.
Of course I could provide some extension utility method which would wrap a RequestBuilder to attach .header("UserAgent") and then I would use it for building all my requests, but I thought maybe I missed some existing and simpler way?
You can use an interceptor to add the User-Agent header to all your requests.
For more information about okHttp interceptors see http://square.github.io/okhttp/interceptors/
Example implementation of this interceptor:
/* This interceptor adds a custom User-Agent. */
public class UserAgentInterceptor implements Interceptor {
private final String userAgent;
public UserAgentInterceptor(String userAgent) {
this.userAgent = userAgent;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.header("User-Agent", userAgent)
.build();
return chain.proceed(requestWithUserAgent);
}
}
Test for the UserAgentInterceptor:
public void testUserAgentIsSetInRequestHeader() throws Exception {
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setBody("OK"));
server.play();
String url = server.getUrl("/").toString();
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new UserAgentInterceptor("foo/bar"));
Request testRequest = new Request.Builder().url(url).build()
String result = client.newCall(testRequest).execute().body().string();
assertEquals("OK", result);
RecordedRequest request = server.takeRequest();
assertEquals("foo/bar", request.getHeader("User-Agent"));
}
In case anyone is looking for this working with OkHttp 3 and in Kotlin:
val client = OkHttpClient.Builder()
.addNetworkInterceptor { chain ->
chain.proceed(
chain.request()
.newBuilder()
.header("User-Agent", "COOL APP 9000")
.build()
)
}
.build()
OkHttp v2.1 which is set to be released in the next few weeks will automatically set a User-Agent header if one is not already set.
As of now there isn't a good way to add this header to every request in a centralized way. The only workaround is to include the header manually for every Request that is created.
Based on #josketres answer, here is a similar Interceptor for OkHttp version 3
public class UserAgentInterceptor implements Interceptor {
private final String mUserAgent;
public UserAgentInterceptor(String userAgent) {
mUserAgent = userAgent;
}
#Override
public Response intercept(#NonNull Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.header("User-Agent", mUserAgent)
.build();
return chain.proceed(request);
}
}
Plus the updated test:
#Test
public void testUserAgentIsSetInRequestHeader() throws IOException, InterruptedException {
final String expectedUserAgent = "foo/bar";
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setBody("OK"));
server.start();
OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
okHttpBuilder.addInterceptor(new UserAgentInterceptor(expectedUserAgent));
Request request = new Request.Builder().url(server.url("/").url()).build();
ResponseBody result = okHttpBuilder.build().newCall(request).execute().body();
assertNotNull(result);
assertEquals("OK", result.string());
assertEquals(expectedUserAgent, server.takeRequest().getHeader("User-Agent"));
}
You have to use builder in newer versions. (Sep 2021)
client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#NotNull
#Override
public Response intercept(#NotNull Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.header("User-Agent", "My Agent is so cool")
.build();
return chain.proceed(requestWithUserAgent);
}
})
.build();
Using an intercepter is no longer required in the newer versions of OkHttp. Adding a user agent is as simple as:
Request request = new Request.Builder()
.url("http://www.publicobject.com/helloworld.txt")
.header("User-Agent", "OkHttp Example")
.build();
Source: OkHttp wiki.

Categories

Resources