如何与改造发送的multipart / form-data的? [英] How to send multipart/form-data with Retrofit?

查看:604
本文介绍了如何与改造发送的multipart / form-data的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想发从文章 Android版的客户端向REST服务器。这里是的的Python 的从服务器模型:

I want to send an Article from and Android client to a REST server. Here is the Python model from the server:

class Article(models.Model):
    author = models.CharField(max_length=256, blank=False)
    photo = models.ImageField()

下面的接口描述前执行:

The following interface describes the former implementation:

@POST("/api/v1/articles/")
public Observable<CreateArticleResponse> createArticle(
        @Body Article article
);

现在我想发送的图像与文章的数据。该照片不是一部分的文章的模型上的的Andr​​oid 的客户端。

Now I want to send an image with the Article data. The photo is not part of the Article model on the Android client.

@Multipart
@POST("/api/v1/articles/")
public Observable<CreateArticleResponse> createArticle(
        @Part("article") Article article,
        @Part("photo") TypedFile photo
);

API是prepared并试验成功的卷曲的。

$ curl -vX POST http://localhost:8000/api/v1/articles/ \
    -H "Content-Type: multipart/form-data" \
    -H "Accept:application/json" \
    -F "author=cURL" \
    -F "photo=@/home/user/Desktop/article-photo.png"

当我通过发送数据createArticle() Android版的客户端收到一条 HTTP 400 状态,说明在字段是必需/缺少

When I send data through createArticle() from the Android client I receive an HTTP 400 status stating that the fields are required/missing.

D  <--- HTTP 400 http://192.168.1.1/articles/ (2670ms)
D  Date: Mon, 20 Apr 2015 12:00:00 GMT
D  Server: WSGIServer/0.1 Python/2.7.8
D  Vary: Accept, Cookie
D  X-Frame-Options: SAMEORIGIN
D  Content-Type: application/json
D  Allow: GET, POST, HEAD, OPTIONS
D  OkHttp-Selected-Protocol: http/1.0
D  OkHttp-Sent-Millis: 1429545450469
D  OkHttp-Received-Millis: 1429545453120
D  {"author":["This field is required."],"photo":["No file was submitted."]}
D  <--- END HTTP (166-byte body)
E  400 BAD REQUEST

这是被接收为 request.data 服务器端:

This is what is received as request.data on the server side:

ipdb> print request.data  
  <QueryDict: {u'article': [u'{"author":"me"}'], \
  u'photo': [<TemporaryUploadedFile: IMG_1759215522.jpg \
  (multipart/form-data)>]}>

如何转换的文章的在一个多对象符合数据类型?我读的改造可能允许使用的变频器了解这一点。它应该是一个实现了 retrofit.mime.TypedOutput 据我了解的的文档

How can convert the Article object in a multipart conform data type? I read that Retrofit might allow to use Converters for this. It should be something that implements a retrofit.mime.TypedOutput as far as I understood for the documentation.

多部分零件使用 RestAdapter 的转换器,也可以实施 TypedOutput 来处理自己的序列化。

Multipart parts use the RestAdapter's converter or they can implement TypedOutput to handle their own serialization.

Related

  • HTML 4.01 Specification - Form submission - multipart/form-data
  • Retrofit Annotation Type Part documentation
  • Upload multipart image data in JSON with Retrofit?
  • REST - HTTP Post Multipart with JSON
  • Retrofit Multipart Upload Image failed
  • Retrofit issue #178: Create manual for sending files with retrofit
  • Retrofit issue #531: Problem uploading file via POST/Multipart
  • Retrofit issue #658: Not able to send string parameters with image when using Multipart
  • Retrofit issue #662: Retrofit Form Encoded and Multipart in single request
  • 推荐答案

    根据您的卷曲的要求,你要创建水木清华这样的:

    According to your curl request you are trying to create smth like this:

    POST http://localhost:8000/api/v1/articles/ HTTP/1.1
    User-Agent: curl/7.30.0
    Host: localhost
    Connection: Keep-Alive
    Accept: application/json
    Content-Length: 183431
    Expect: 100-continue
    Content-Type: multipart/form-data; boundary=----------------------------23473c7acabb
    
    ------------------------------23473c7acabb
    Content-Disposition: form-data; name="author"
    
    cURL
    ------------------------------23473c7acabb
    Content-Disposition: form-data; name="photo"; filename="article-photo.png"
    Content-Type: application/octet-stream
    
    ‰PNG
    
    <!RAW BYTES HERE!>
    
    M\UUÕ+4qUUU¯°WUUU¿×ß¿þ Naa…k¿    IEND®B`‚
    ------------------------------23473c7acabb--
    

    通过申请可以在接下来的方式创建改装适配器:

    With retrofit adapter this request can be created in a next way:

    @Multipart
    @POST("/api/v1/articles/")
    Observable<Response> uploadFile(@Part("author") TypedString authorString,
                                    @Part("photo") TypedFile photoFile);
    

    用法:

    TypedString author = new TypedString("cURL");
    File photoFile = new File("/home/user/Desktop/article-photo.png");
    TypedFile photoTypedFile = new TypedFile("image/*", photoFile);
    retrofitAdapter.uploadFile(author, photoTypedFile)
                   .subscribe(<...>);
    

    它创建类似的输出:

    Which creates similar output:

    POST http://localhost:8000/api/v1/articles/ HTTP/1.1
    Content-Type: multipart/form-data; boundary=32230279-83af-4480-abfc-88a880b21b19
    Content-Length: 709
    Host: localhost
    Connection: Keep-Alive
    Accept-Encoding: gzip
    User-Agent: okhttp/2.3.0
    
    --32230279-83af-4480-abfc-88a880b21b19
    Content-Disposition: form-data; name="author"
    Content-Type: text/plain; charset=UTF-8
    Content-Length: 4
    Content-Transfer-Encoding: binary
    
    cUrl
    --32230279-83af-4480-abfc-88a880b21b19
    Content-Disposition: form-data; name="photo"; filename="article-photo.png"
    Content-Type: image/*
    Content-Length: 254
    Content-Transfer-Encoding: binary
    
    <!RAW BYTES HERE!>
    
    --32230279-83af-4480-abfc-88a880b21b19--
    

    这里的关键区别是,你使用POJO 第三条为多部分参数,默认情况下是由转换器转换成JSON。而你的服务器预计普通字符串代替。随着袅袅您发送卷曲,不是 {作者:卷曲}

    The key difference here is that you used POJO Article article as multipart param, which by default is converted by Converter into json. And your server expects plain string instead. With curl you are sending cURL, not {"author":"cURL"}.

    这篇关于如何与改造发送的multipart / form-data的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆