android - 使用 Retrofit 1.8.0 的多部分请求不起作用

标签 android multipart retrofit

我有大约 4 天的时间,尝试在 android 中使用 Retrofit 1.8.0 发出多部分请求并取得成功。我的界面看起来像这样

@Multipart
@POST("/posts/add.json") 
void addComment(
  @Part("id") String id,
  @Part("post[body]") String body,
  @Part("post[attachment]") TypedFile attachment,
  Callback<Map<String, String>> callback );

但是,在服务器端,我收到以下信息

Parameters: {"id"=># <File:/var/folders/z0/0ggjvvfj4t1fdsvbxf3lc9pw0000gn/T/RackMultipart9853-0>, "post"=>{"body"=>#<File:/var/folders/z0/0ggjvvfj4t1fdsvbxf3lc9pw0000gn/T/RackMultipart9853-1>, "attachment"=>#<File:/var/folders/z0/0ggjvvfj4t1fdsvbxf3lc9pw0000gn/T/RackMultipart9853-2>}, "controller"=>"posts", "action"=>"add", "format"=>"json"}

如您所见,文件部分在每个部分都发送它,但我缺少参数值 id 和 post[body]

这就是 Retrofit 试图发送的内容

 02-06 15:01:16.213    32545-822/com.myapp D/Retrofit﹕ --fe41634b-6826-4ee4-95cb-65efb0ca66c2
Content-Disposition: form-data; name="id"
Content-Type: text/plain; charset=UTF-8
Content-Length: 3
Content-Transfer-Encoding: binary
189
--fe41634b-6826-4ee4-95cb-65efb0ca66c2
Content-Disposition: form-data; name="post[body]"
Content-Type: text/plain; charset=UTF-8
Content-Length: 4
Content-Transfer-Encoding: binary
test
--fe41634b-6826-4ee4-95cb-65efb0ca66c2
Content-Disposition: form-data; name="post[attachment]"; filename="IMG_20140203_144358.jpg"
Content-Type: image/jpg
Content-Length: 1615460
Content-Transfer-Encoding: binary
����/�Exif����MM��*���������

这是 HttpMime 库在 Multipart 中发送的内容,不同之处在于针对 Retrofit 的“Content-Transfer-Encoding” header

Content-Disposition: form-data; name="id"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit

Content-Disposition: form-data; name=“post[body]"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit

Content-Disposition: form-data; name=“post[attachment]"; filename="images.jpg"
Content-Type: image/jpg
Content-Transfer-Encoding: binary

有什么线索吗?提前致谢

--------------------------------解决方案------------ ----------------------

最后,我是这样解决的,其实我的答案和@lazypig很接近,这是一个很好的指导方针

我唯一改变的是他的类“ByteArrayTypedOutput”

我创建了一个名为“MultipartTypedOutputCustom”的类 http://pastie.org/10549360

这就是我的界面现在的样子

“PostsRetrofitAPI.java”类

@POST("/posts/add.json")
    void addComment(@Body MultipartTypedOutputCustom parts,
                    Callback<Map<String, String>> callback);

“PostsService.java”类

//Properties
private PostsRetrofitAPI mApi;
...

    @Override
        public void addComment(ServiceResponseHandler<Map<String, String>> handler, String id, String body, TypedFile attachment) {
           MultipartTypedOutputCustom parts = new MultipartTypedOutputCustom();
           parts.addPart("id", new TypedString(id));
           parts.addPart("post[body]", new TypedString(body));
           parts.addPart("post[attachment]", attachment);
    objectRetrofitCallback= new ObjectRetrofitCallback(handler, ServerError.class, ClientError.class);
            mApi.addComment(parts, objectRetrofitCallback);
        }

最佳答案

如果您在 http://square.github.io/retrofit/ 上看到示例“id”和“part[body]”参数的对象类型需要是 TypedString 而不是 String。 TypedString 设置适当的 MIME 类型并转换为字节:

https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/mime/TypedString.java

关于android - 使用 Retrofit 1.8.0 的多部分请求不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21582453/

相关文章:

android - 追加问号到url改造android

android - 我应该如何将 Dagger2 与 Retrofit 一起使用?

android Listview删除一个项目并刷新列表

android - 在Android Studio中将Gradle从3.3升级到4.1后出现错误

rest - 如何使用多部分使用 Postman 将文件上传到 Google 驱动器?

android Volley,RequestQueue中的cancelAll和stop方法有什么区别

java - Spring 支持 MIME 类型 "multipart/byteranges"

java - ClientHandlerException : MIME media type, 多部分/表单数据,未找到

android - 如何检测或拦截移动设备中第三方应用程序发出的每个网络调用?

android - 如何在 Qt 中使用 Google-Cloud-Messaging API