EzDevInfo.com

retrofit

Type-safe HTTP client for Android and Java by Square, Inc. Retrofit a type-safe http client for android and java

Logging with Retrofit 2

I'm trying to get the exact JSON that is being sent in the request. Here is my code:

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
   @Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
      Request request = chain.request();
      Log.e(String.format("\nrequest:\n%s\nheaders:\n%s",
                          request.body().toString(), request.headers()));
      com.squareup.okhttp.Response response = chain.proceed(request);
      return response;
   }
});
Retrofit retrofit = new Retrofit.Builder()
   .baseUrl(API_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(client).build();

But I only see this in the logs:

request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json

How am I supposed to do proper logging, given the removal of setLog() and setLogLevel() which we used to use with Retrofit 1?


Source: (StackOverflow)

Android Retrofit - onProgressUpdate for showing Progress Notification

I'm currently using Retrofit by Square for Android network communications. Is there a way to get its progress during a task to create a progress notification, something similar to that which Facebook uses when uploading an image?

Use Case would be to load an image hopefully of full image quality without compression or scaling.

I see how it is possible with an asynctask but that would defeat the purpose of using Retrofit. However that might be the route I would have to take.


Source: (StackOverflow)

Advertisements

How can I return String or JSONObject from asynchronous callback using Retrofit?

For example, calling

api.getUserName(userId, new Callback<String>() {...});

cause:

retrofit.RetrofitError: retrofit.converter.ConversionException:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 
Expected a string but was BEGIN_OBJECT at line 1 column 2

I think I must disable gson parsing into POJOs but can't figure out how to do it.


Source: (StackOverflow)

How to set a timeout in Retrofit library?

I am using Retrofit library in my app, and I'd like to set a timeout of 60 seconds. Does Retrofit have some way to do this?

I set Retrofit this way:

RestAdapter restAdapter = new RestAdapter.Builder()
    .setServer(BuildConfig.BASE_URL)
    .setConverter(new GsonConverter(gson))
    .build();

How can I set the timeout?


Source: (StackOverflow)

(Retrofit) Could not locate converter for class crashing app

So Retrofit 2.0.0 was recently released and theres not really any updated examples on how to use it, but im trying to implement it for a basic API call. Im getting a

java.lang.IllegalArgumentException: Unable to create converter for class` 

caused by

Caused by: java.lang.IllegalArgumentException: Could not locate converter for class orbyt.app.dataclass. Tried:
* retrofit.OkHttpBodyConverterFactory

When trying to make the api call.


Source: (StackOverflow)

Uploading file on server using retrofit

In my project, I've got to send an image taken from android device to server site, where it should be stored on disk. Unfortunately, when I call the method on the device site I meet this error:

DEBUG/Retrofit(4429): java.lang.RuntimeException: 
    Unable to write multipart request.
at retrofit.mime.MultipartTypedOutput.buildPart(MultipartTypedOutput.java:86)
at retrofit.mime.MultipartTypedOutput.addPart(MultipartTypedOutput.java:49)
at retrofit.RequestBuilder.setArguments(RequestBuilder.java:211)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:264)
at retrofit.RestAdapter$RestHandler.access$500(RestAdapter.java:197)
at retrofit.RestAdapter$RestHandler$1.obtainResponse(RestAdapter.java:243)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:38)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at retrofit.Platform$Android$2$1.run(Platform.java:134)
at java.lang.Thread.run(Thread.java:856)

Caused by: java.io.FileNotFoundException: /external/images/media/1270: 
    open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:416)
at java.io.FileInputStream.<init>(FileInputStream.java:78)
at retrofit.mime.TypedFile.writeTo(TypedFile.java:74)
at retrofit.mime.MultipartTypedOutput.buildPart(MultipartTypedOutput.java:83)
... 10 more

Caused by: libcore.io.ErrnoException: 
    open failed: ENOENT (No such file or directory)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
at libcore.io.IoBridge.open(IoBridge.java:400)
... 13 more

That's the method's declaration

@Multipart
@POST("/monument/photo/upload")
void addMonumentPhoto(@Part("MonumentID") int monumentId,
                      @Part("name") String name,
                      @Part("subscript") String subscript,
                      @Part("photo") TypedFile photo,
                      Callback<Photo> callback);

... and that's how I call it

photo = new File(selectedImageUri.getPath());
typedFile = new TypedFile("application/octet-stream", photo);
MonumentsUtil.getApi().addMonumentPhoto(monument.getIdZabytek(),
      "podpis",
      "Main photo",
      typedFile,
      new Callback<Photo>() {
    @Override
    public void success(Photo aPhoto, Response response) {
    }

    @Override
    public void failure(RetrofitError retrofitError) {
         Log.e(TAG, retrofitError.getMessage());
    }
});

On the server's site I've got such methods:

@RequestMapping(value="/monument/photo/upload", method=RequestMethod.POST)
public @ResponseBody Photo requestMonumentPhotoAdd(
       @RequestParam("MonumentID") int monumentId,
       @RequestParam("name") String name ,
       @RequestParam("subscript") String subscript,
       @RequestParam("photo") org.springframework.web.multipart.MultipartFile file) {

    Photo photo = new Photo();
    photo.setIdZabytek(monumentId);
    photo.setUri(URL+ "/images/" + name);
    photo.setPodpis(subscript);
    photo = monumentsRepo.addPhoto(photo);
    String filePath = "D:\\Projekty\\Images\\" + monumentId + ":" + photo.getIdZjecia();

    if (!file.isEmpty()) {
        try {
            byte[] bytes = file.getBytes();
            BufferedOutputStream stream = new BufferedOutputStream(
                new FileOutputStream(new File(filePath)));
            stream.write(bytes);
            stream.close();
            photo.setUri(filePath);
            monumentsRepo.updatePhoto(photo);
            return photo;
        } catch (Exception e) {
            return null;
        }
    } else {
        return null;
    }
}

The program get to the failure block and I don't know why. Can anybody point the mistake and explain what's wrong?

EDIT

After correction in my code I've got next error which I can't fix:

java.net.ProtocolException: content-length promised 1431984 bytes, but received 0      
    com.squareup.okhttp.internal.http.RetryableOutputStream.close(RetryableOutputStream.java:52),
    com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:629),
    com.squareup.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java: 346),
    com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:295),
    com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:489), 
retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:90), 
retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:48), 
retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:287), 
retrofit.RestAdapter$RestHandler.access$500(RestAdapter.java:197), 
retrofit.RestAdapter$RestHandler$1.obtainResponse(RestAdapter.java:243), 
retrofit.CallbackRunnable.run(CallbackRunnable.java:38), 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076), 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569), 
retrofit.Platform$Android$2$1.run(Platform.java:134), 
java.lang.Thread.run(Thread.java:856)

and the HTTP Response

HTTP/1.1 400 Bad Request, 
Connection: close, 
Content-Length: 1068, 
Content-Type:     text/html;charset=utf-8, 
Date: Wed, 11 Dec 2013 16:45:39 GMT,  
OkHttp-Received-Millis: 1386780339873, 
OkHttp-Response-Source: NETWORK 400,
OkHttp-Selected-Transport: http/1.1, 
OkHttp-Sent-Millis: 1386780339799, Server: Apache-Coyote/1.1

I think that the server's method could be wrongly written but I'm not sure. Could anybody help with it?


Source: (StackOverflow)

Java/Retrofit/Robospice: multiple parameters in @GET command?

I am using Retrofit and Robospice to make api calls in my android application. All @POST methods work great, and so do @GET commands without any parameters in the URL, but I can't get any @GET calls to work with parameters on the end!

For example, if my api path was "my/api/call/" and I wanted 2 parameters "param1" and "param2" in the url, the get call would look like:

http://www.mysite.com/my/api/call?param1=value1&param2=value2

so I have setup my @GET interface like so:

@GET("/my/api/call?param1={p1}&param2={p2}")
Response getMyThing(@Path("p1")
String param1, @Path("p2")
String param2);

but i get an error saying "An exception occurred during request network execution :URL query string "/my/api/call?param1={p1}&param2={p2}" on method getMyThing may not have replace block."

What am I doing wrong?


Source: (StackOverflow)

Using Retrofit in Android

I have an android app that has 3 activities :

  1. A login activity
  2. A tasks acivity where all tasks pertaining to a user are displayed (Populated using an Array Adapter)
  3. A task_details activity which results from clicking a task on the list

I have to consume REST Apis. The research I have done so far directs me to use Retrofit. I checked how to use it and found out that :

  1. Set the base URL in the Main Activity (Mine is the Login Activity)
  2. I need to create a API class and define my functions using annotations.
  3. Use the class Rest Adapter in the Activity and define Callbacks.

Had my app been a single activity app, I would have crunched everything in my MainActivity.java but I don't know how and where to put all the code from steps 1,2,3 for use in my 3 activities.Could you please help by telling how to use Retrofit in my app. Thanks a lot.

Specifically, I need network calls to : 1. Login the user 2. Get all the tasks of the user. And for both I would be using a given REST api.


Source: (StackOverflow)

How to implement an async Callback using Square's Retrofit networking library

As an iOS developer beginning to work with Android I came across Retrofit. I understand how to implement synchronous requests but am having trouble implementing asynchronous requests with success/failure callbacks. Specifically, the Callback syntax is unclear to me and there are no concrete examples of how to do this on the Retrofit website, the Square blogpost introducing Retrofit, or elsewhere that I've seen. Can someone please post some example code on this? I filed an issue in the Retrofit repo asking that they update the README with this info.


Source: (StackOverflow)

Is there a way to set a base request parameter to be included in every request made with Square's Retrofit library?

I'm using Square's Retrofit library for short-lived network calls. There are a few pieces of data that I include as @Query params on every request. Like so:

@GET("/thingOne.php")
void thingOne(
        @Query("app_version") String appVersion,
        @Query("device_type") String deviceType,
        Callback<Map<String,Object>> callback
);

@GET("/thingTwo.php")
void thingTwo(
        @Query("app_version") String appVersion,
        @Query("device_type") String deviceType,
        Callback<Map<String,Object>> callback
);

It's cumbersome to have to define appVersion and deviceType for every single endpoint outlined in the Interface. Is there a way to set a base set of parameters that should be included with every request? Something similar to how we set a common Authorization Header?

RestAdapter restAdapter = new RestAdapter.Builder()
    .setServer("...")
    .setRequestHeaders(new RequestHeaders() {
        @Override
        public List<Header> get() {
            List<Header> headers = new ArrayList<Header>();
                Header authHeader = new Header(
                    "Authorization", "Bearer " + token);
                headers.add(authHeader);
            }
            return headers;
        }
    })
    .build();
this.service = restAdapter.create(ClientInterface.class);

Source: (StackOverflow)

Using Retrofit to access JSON arrays

I thought I understood how to do this, but obviously not. I have my API from Flickr, which begins like so:

jsonFlickrApi({
   "photos":{
      "page":1,
      "pages":10,
      "perpage":100,
      "total":1000,
      "photo":[
         {
            "id":"12567883725",
            "owner":"74574845@N05",
            "secret":"a7431762dd",
            "server":"7458",
            "farm":8,
            "title":"",
            "ispublic":1,
            "isfriend":0,
            "isfamily":0,
            "url_l":"http:\/\/farm8.staticflickr.com\/7458\/12567883725_a7431762dd_b.jpg",
            "height_l":"683",
            "width_l":"1024"
         }

Now the information I need to get is from within the photo array, so what I have been trying to do is:

interface ArtService {

    @GET("/services/rest/?method=flickr.photos.getRecent&extras=url_l&owner_name&format=json")
    PhotosResponse getPhotos();

    public class PhotosResponse {
        Photos photos;
    }

    public class Photos {
        List<Arraz> photo;
    }

    public class Arraz {
        int id;
        String title;
        String owner;
        String url_l;
    }
}

Very clear that I seem to be missing the point, however I am unsure of how to get the information..


Source: (StackOverflow)

Square retrofit server mock for testing

What's the best way to mock a server for testing when using the square retrofit framework.

Potential ways:

  1. Create a new retrofit client and set it in the RestAdapter.Builder().setClient(). This involves parsing the Request object and returning the json as a Response object.

  2. Implement this annotated interface as a mock class and use that in place of the version provided by RestAdapter.create() (wont test gson serialisation)

  3. ?

Ideally I want to have the mocked server provide json responses so I can test the gson serialisation at the same time.

Any examples would be greatly appreciated.


Source: (StackOverflow)

Getting JSON from RetrofitError object using Retrofit 1.2.2

I am using the Retrofit library to do REST calls to a service I am using.

If I make an API call to my service and have a failure, the service returns a bit of JSON along with the standard HTTP error stuff. Using the RetrofitError object included in the failure callback I am able to find the HTTP status code and several other things, however I am not able to retrieve the JSON that the service sends back.

For example, let's say I make a call to the API where I am trying to create a user. If the username already exists the service will return a 400 error code along with some JSON like this:

{"error":"Username already in use"}

Because a simple 400 error code isn't specific enough I really need access to the JSON that is returned.

Does anyone know how I can get at this JSON data? I have tried looking at every field in the RetrofitError object and can't find it anywhere. Is there something additional I need to be doing?


Source: (StackOverflow)

Retrofit callback get response body

I am testing retrofit to compare it with volley and i am struggling to get the response from my requests.

For example, I do something like this:

RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://localhost:8080")
            .build();

MyService service = restAdapter.create(MyService.class);
service.getToto("toto", new Callback<Toto>() {
        @Override
        public void success(Toto toto, Response response) {

            //Try to get response body
            BufferedReader reader = null;
            StringBuilder sb = new StringBuilder();
            try {

                reader = new BufferedReader(new InputStreamReader(response.getBody().in()));

                String line;

                try {
                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }


            String result = sb.toString();
        }

        @Override
        public void failure(RetrofitError error) {

        }
    });

It works, the object toto is set, but for testing purposes, I also want to display the json response return by the server.

So I am trying to read the InputStream from response.getBody() which is a TypedInputStream. Unfortunately, I always get an IOException : Stream is closed

I tried to use the Utils class from retrofit but I get the same IOException error.


Source: (StackOverflow)

When should one use RxJava Observable and when simple Callback on Android?

I'm working on networking for my app. Desided to try out Square's Retrofit. I see that they support simple Callback

@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);

and RxJava's Observable

@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);

Both look pretty similar at first glance. But when it gets to implementation it gets interesting...

While with simple callback implementation would look similar to this:

api.getUserPhoto(photoId, new Callback<Photo>() {
    @Override
    public void onSuccess() {
    }
});

which is quite simple and straightforward. And with Observable it quickly gets verbose and quite complicated.

public Observable<Photo> getUserPhoto(final int photoId) {
    return Observable.create(new Observable.OnSubscribeFunc<Photo>() {
        @Override
        public Subscription onSubscribe(Observer<? super Photo> observer) {
            try {
                observer.onNext(api.getUserPhoto(photoId));
                observer.onCompleted();
            } catch (Exception e) {
                observer.onError(e);
            }

            return Subscriptions.empty();
        }
    }).subscribeOn(Schedulers.threadPoolForIO());
}

And that is not it. You still have to do something like this:

Observable.from(photoIdArray)
        .mapMany(new Func1<String, Observable<Photo>>() {
            @Override
            public Observable<Photo> call(Integer s) {
                return getUserPhoto(s);
            }
        })
        .subscribeOn(Schedulers.threadPoolForIO())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Photo>() {
            @Override
            public void call(Photo photo) {
                //save photo?
            }
        });

Am I missing something here? Or is this a wrong case to use Observables? When would/should one prefer Observable over simple Callback?

Update

Using retrofit is much simpler than example above as @Niels showed in his answer or in Jake Wharton's example project U2020. But essentially the question stays the same - when should one use one way or the other?


Source: (StackOverflow)