我正在尝试使用Robospice with Retrofit将图像上传到我的Google appengine blobstore。 我可以获取GAE提供的上传URL,但是当我尝试将带有图像的URL作为Multipart POST发送时,我得到一个例外:
E // RequestRunner.java:134(24689):Thread-3363请求网络执行期间发生异常: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):在ginger.connexus.network.UploadImage.loadDataFromNetwork(UploadImage.java:24)
E // RequestRunner.java:134(24689):在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):发送进度完成
我的API界面
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);
}
}
我的执行电话
UploadImage upload = new UploadImage(uploadUrl, streamId, file);
getSpiceManager().execute(upload, new MyImageUploadListener());
答案 0 :(得分:9)
尝试使用@EncodedPath
代替@Path
并自行进行网址编码。
public interface MyApi {
@Multipart
@POST("/{uploadurl}")
MyImage uploadImage(@EncodedPath("uploadurl") String uploadUrlEncoded,
... );
}
要处理“%2F”问题,我会使用下一个代码段
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", "/");