I am trying to use retrofit 2.3 in my Android App.
I have following url format :
www.test.com/api?url=a?response=json.
How this URL will be casted to QueryParam? For first part www.test.com/api will be my base URL then #Query("url") value but how to handle responsetype=json after second '?'
it should be possible to also add this as query parameter
e.g.:
Call<TestSiteResult> getTestSiteInfo(#Query("url") String yourUrl, #Query("response") String responseType)
If this response parameter is needed always you can also consider using an OkHttpClient for the HTTP connection (you can simply add it with the client(OkHttpClient) method of the Retrofit.Builder) which is responsible for intercepting URLs and append a certain parameter to your URL (e.g. i used this for the interception of api keys).
A LoggingInterceptor could look like this:
public class TestLoggingInterceptor implements Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
HttpUrl originalHttpUrl = original.url();
HttpUrl url = originalHttpUrl.newBuilder()
.addQueryParameter("response", "json")
.build();
Request.Builder requestBuilder = original.newBuilder();
.url(url);
Request request = requestBuilder.build;
return chain.proceed(request);
}
}
I hope this can help you.
Related
How can we intercept java.net.HttpURLConnection network requests? However, we can achieve interception using OKHTTPClient. Please help.
If you want to modify request/response with OkHttpClient you can use interceptors. For example If you want to add a header to all requests, you can use the code below. Modifying other parts like body is similar.
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder().header("Authorization",
Credentials.basic("aUsername", "aPassword"));
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
}).build();
My app uses dynamic URLs to make web-service calls (on Android). baseUrl is set as empty and we pass Retrofit2 #Url parameters in the service interface:
public interface UserService {
#GET
public Call<ResponseBody> profilePicture(#Url String url);
}
We don't know the host/domain in advance, so MockWebServer is not able to intercept the requests. The call to fetch the initial list of dynamic URLs is made in different screens. One idea is to create a new flavor providing a local data source for URLs to be used, which is my fallback plan.
I am curious if MockWebServer has any other methods to help test such cases and can be limited to test code.
You could use an OkHttp interceptor to rewrite the hostname and port?
I was also facing the same kind of issue. When I use MockWebserver in testing I have to change base URL to target mock web server localhost and port. I tried this it is working fine.
private static final Interceptor mRequestInterceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
final InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 8080);
HttpUrl httpUrl = request.url().newBuilder().scheme("http://").host(address.getHostName()).port(8080)
.build();
request = request.newBuilder()
.url(httpUrl)
.build();
return chain.proceed(request);
}
};
After this base url changes to "http://localhost:8080/"
I am trying to compute a checksum from HTTP arguments dynamically. And then I would like to add this checksum as an HTTP argument.
I need to get the fields that are passed in as parameters first, but it looks like retrofit can only access url query parameters.
#Gordak shows the way to get query parameter, but what I want to achive, if any possible, to get post parameters in the request chain.
Okay, here we go.
First, build your OkHTTP client and retrofit object.
OkHttpClient client = httpBuilder
.addNetworkInterceptor(INTERCEPTOR_REQUEST_ADD_CHECKSUM)
.build();
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.baseUrl("https://my.domain.com")
.build();
Then, you need to define your interceptor :
private static final Interceptor INTERCEPTOR_REQUEST_ADD_CHECKSUM = new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
HttpUrl url = chain.request().url();
String param1 = url.queryParameter("param1");
String param2 = url.queryParameter("param2");
String chk = aMethodToComputeChecksum(param1,param2);
url = url.newBuilder().addQueryParameter("checksum", chk).build();
Request request = chain.request().newBuilder().url(url).build();
return chain.proceed(request);
}
Maybe it will help - try to compute this parameter once and write it in RequestInterceptor
I'm using Retrofit library version 2 with OkHttpClient.
I want to get some header from all responses.
I found one solution with OkClient:
public class InterceptingOkClient extends OkClient{
public InterceptingOkClient()
{
}
public InterceptingOkClient(OkHttpClient client)
{
super(client);
}
#Override
public Response execute(Request request) throws IOException
{
Response response = super.execute(request);
for (Header header : response.getHeaders())
{
// do something with header
}
return response;
}
}
But how i can do this if i'm using OkHttpClient?
Yes, this is old question.. but still found to answer because myself too was searching similar one.
okHttpClient.interceptors().add(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", "auth-value"); // <-- this is the important line, to add new header - replaces value with same header name.
Request request = requestBuilder.build();
Response response = chain.proceed(request);
Headers allHeaders = response.headers();
String headerValue = allHeaders.get("headerName");
return response;
}
});
Hope, this helps!
P.S: no error handled.
You can use the logging interceptor for that. Add it as an interceptor to your OkHttpClient builder while building the client, set the log level and voila! You will have all the information regarding the request as well as the response.
Here's how you can add the interceptor -
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpBuilder.addInterceptor(loggingInterceptor);
client = okHttpBuilder.build();
There are four options when it comes to what you want to Log - NONE,BASIC,HEADERS, and BODY.
Now build the the retrofit instance with the above defined client and you will have all the data you need.
So some images I request require an authentication header to be added
I am using Retrofit 2.0 which has this OkHttp client with a interceptor to add the user token to the header to every request
okHttpClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request(); //Current Request
Request requestWithToken = null; //The request with the access token which we will use if we have one instead of the original
requestWithToken = originalRequest.newBuilder().addHeader(Constants.UrlParamConstants.HEADER_AUTHORIZATION,String.format(Constants.UrlParamConstants.HEADER_AUTHORIZATION_VALUE, MyApplication.getInstance().getUser().getApiToken())).build();
Response response = chain.proceed((requestWithToken != null ? requestWithToken : originalRequest)); //proceed with the request and get the response
return response;
}
});
I would like to know how can I set the same okHttp client instance for Fresco library.
I am aware that you need to add this dependency to use OkHttp with Fresco but how about setting the client?
compile "com.facebook.fresco:imagepipeline-okhttp:0.8.0+"
At the end of the day I just need to set authentication header for an image request
thanks for reading
http://frescolib.org/docs/using-other-network-layers.html
Context context;
OkHttpClient okHttpClient; // build on your own
ImagePipelineConfig config = OkHttpImagePipelineConfigFactory
.newBuilder(context, okHttpClient)
. // other setters
. // setNetworkFetcher is already called for you
.build();
Fresco.initialize(context, config);