Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uploading an image to Google appengine using Robospice with Retrofit

I'm trying to use Robospice with Retrofit to upload an image to my Google appengine blobstore. I can get the upload URL provided by GAE, but when I try to send the URL with the image as a Multipart POST I get an exception:

E//RequestRunner.java:134(24689): Thread-3363 An exception occurred during request network execution:null

E//RequestRunner.java:134(24689): retrofit.RetrofitError

E//RequestRunner.java:134(24689): at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:343)

E//RequestRunner.java:134(24689): at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:222)

E//RequestRunner.java:134(24689): at $Proxy0.uploadImage(Native Method)

E//RequestRunner.java:134(24689): at ginger.connexus.network.UploadImage.loadDataFromNetwork(UploadImage.java:24)

E//RequestRunner.java:134(24689): at ginger.connexus.network.UploadImage.loadDataFromNetwork(UploadImage.java:1)

E//RequestRunner.java:134(24689): at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:45)

E//RequestRunner.java:134(24689): at com.octo.android.robospice.request.RequestRunner.processRequest(RequestRunner.java:130)

E//RequestRunner.java:134(24689): at com.octo.android.robospice.request.RequestRunner$1.run(RequestRunner.java:197)

E//RequestRunner.java:134(24689): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)

E//RequestRunner.java:134(24689): at java.util.concurrent.FutureTask.run(FutureTask.java:234)

E//RequestRunner.java:134(24689): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)

E//RequestRunner.java:134(24689): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)

E//RequestRunner.java:134(24689): at java.lang.Thread.run(Thread.java:841)

D//RequestProgressManager.java:75(24689): Sending progress COMPLETE

My API interface

public interface MyApi {
    @Multipart
    @POST("/{uploadurl}")
    MyImage uploadImage(
            @Path("uploadurl") String uploadurl,
            @Part("stream") long streamId,
            @Part("image") TypedFile image);
}

My Retrofit Gson Spice Service

public class MyService extends RetrofitGsonSpiceService {

    private final static String BASE_URL = "theinternet";

    @Override
    protected String getServerUrl() {
        return BASE_URL;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        addRetrofitInterface(MyApi.class);
    }

}

My Retrofit Spice Request class

public class UploadImage extends RetrofitSpiceRequest<MyImage, MyApi> {

    private final String uploadurl;
    private final long streamId;
    private final TypedFile image;

    public UploadImage(String uploadurl, long streamId, File image) {
            super(MyImage.class, MyApi.class);
            this.uploadurl = uploadurl;
            this.streamId = streamId;
            this.image = new TypedFile("image/jpeg", image);
    }

    @Override
    public MyImage loadDataFromNetwork() throws Exception {
        return getService().uploadImage(uploadurl, streamId, image);
    }
}

My execute call

UploadImage upload = new UploadImage(uploadUrl, streamId, file);
getSpiceManager().execute(upload, new MyImageUploadListener());
like image 928
zachwhaley Avatar asked Jan 13 '23 04:01

zachwhaley


1 Answers

Try to use @EncodedPath instead of @Path and do URL encoding yourself.

public interface MyApi {

    @Multipart
    @POST("/{uploadurl}")
    MyImage uploadImage(@EncodedPath("uploadurl") String uploadUrlEncoded,
            ... );
}

To deal with "%2F" issue i would use next snippet

String encodedValue = URLEncoder.encode(String.valueOf(uploadUrl), "UTF-8");
// URLEncoder encodes for use as a query parameter. Path encoding uses %20 to
// encode spaces rather than +. Query encoding difference specified in HTML spec.
// Any remaining plus signs represent spaces as already URLEncoded.
encodedValue = encodedValue.replace("+", "%20");
String uploadUrlEncoded = encodedValue.replace("%2F", "/");
like image 188
Sergii Pechenizkyi Avatar answered Apr 30 '23 09:04

Sergii Pechenizkyi