Custom Downloader using Picasso - android

I have to download an image from a URL which requires some headers ( username,password) along with the request. So i am doing that using the code given here. But calling this function gives the error
java.lang.NoClassDefFoundError: com.squareup.okhttp.OkHttpClient
at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:72)
I am using Picasso 2.3.3 and okhttp-urlconnection-2.0.0-RC2 libraries
The issue has been raised in this post also but changing to 2.3.2 doesnt work.

Do you have OkHttp included in your project? If not, the problem is that you're using the OkHttpDownloader. You can include the OkHttp library in your project or just UrlConnectionDownloader like below.
This was the result I ended up with.
public static Picasso getImageLoader(Context ctx) {
Picasso.Builder builder = new Picasso.Builder(ctx);
builder.downloader(new UrlConnectionDownloader(ctx) {
#Override
protected HttpURLConnection openConnection(Uri uri) throws IOException {
HttpURLConnection connection = super.openConnection(uri);
connection.setRequestProperty("X-HEADER", "VAL");
return connection;
}
});
return builder.build();
}

Since Picasso 2.5.0 OkHttpDownloader class has been changed, so you have to do something like this:
OkHttpClient picassoClient = new OkHttpClient();
picassoClient.networkinterceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("X-HEADER", "VAL")
.build();
return chain.proceed(newRequest);
}
});
new Picasso.Builder(context).downloader(new OkHttpDownloader(picassoClient)).build();
Source: https://github.com/square/picasso/issues/900

Related

Passing header to Picasso while viewing the image using url - Android

I need to pass a header when I try to show a image using Picasso.
Can any one suggest how to add header to picasso while viewing the image.
You can use downloader for that:
https://github.com/JakeWharton/picasso2-okhttp3-downloader
Example:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("custom-header", "custom-header-value")
.build();
return chain.proceed(newRequest);
}
})
.build();
Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(client))
.build();
Keep in mind that if you are using OkHttpClient already, you should use that instance or create new one using client.newBuilder(). This way, both instances will be using the same request queue.

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)

How to get headers from all responses using retrofit

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.

Android Picasso Authorization header not working

I'am trying to addHeader to the Picasso request, so I've searched and followed what suggested to do, in this case adding an interceptor.But it's not working and not giving any error.
new Picasso.Builder(mContext).downloader(RestAsyncHttpClient.getOkHttpDownloader(header)).build()
.load("https://myUrl.jpg").into(mMediaImageView);
And my okhttpDownload:
public static OkHttpDownloader getOkHttpDownloader(final HashMap<String, String> headers) {
OkHttpClient okHttpClient = mHttpClient.clone();
okHttpClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Builder builder = chain.request().newBuilder();
if (!headers.isEmpty())
for (Entry<String, String> entry : headers.entrySet())
builder.addHeader(entry.getValue(), entry.getKey());
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
});
return new OkHttpDownloader(okHttpClient);
}
I've copied the header and the request and tried in postMan app and everything worked, I've also implemented OnImageLoadFailed but it's not triggered so i can't understand.
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
String test = "sad";
}
The problem wasn't Picasso or OkHhtp everything is at it should, but the problem was i made a mistake adding the header i was putting "MY TOKEN" "Authorization" instead of "Authorization" "MY TOKEN. i will not delete the post because it contains a snippet of "how to add an header to Picasso"

Get redirected URL from Picasso

I'm fetching my images using the following code:
Picasso.with(mContext)
.load(myImage.getUrl())
.fetch();
myImage.getUrl() returns a URL from my server, which will redirect to the actual image hosted on another server. Is there a way to catch the URL my server returns to Picasso? I know I can use a Callback in .fetch(), but that's all I know. I'm using OkHttp as well.
OkHttp allows you not to follow redirects automatically:
OkHttpClient client = new OkHttpClient();
client.setFollowRedirects(false);
You can read the response, get the redirect URL and then forward it manually to Picasso.
EDIT:
Interceptors are feasible as well:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
// process response here
return response;
}
});
I fixed it by this code.
val downloader = OkHttp3Downloader(context)
Picasso.Builder(context).downloader(downloader).build()
Check this for detail.
https://github.com/square/picasso/issues/463
Add okhttp dependency
compile 'com.squareup.okhttp:okhttp:2.5.0'
and try this code
Picasso.Builder builder = new Picasso.Builder(context);
builder.downloader(new OkHttpDownloader(context));
builder.build()
.load(path.trim())
.into(imageView);
This code working for me

Categories

Resources