JJD*_*JJD 29 android multipartform-data image-uploading retrofit
我想将一个文章和Android客户端发送到REST服务器.以下是服务器的Python模型:
class Article(models.Model):
author = models.CharField(max_length=256, blank=False)
photo = models.ImageField()
Run Code Online (Sandbox Code Playgroud)
以下界面描述了以前的实现:
@POST("/api/v1/articles/")
public Observable<CreateArticleResponse> createArticle(
@Body Article article
);
Run Code Online (Sandbox Code Playgroud)
现在我想发送带有文章数据的图像.该photo不是的部分文章的型号的Android客户端.
@Multipart
@POST("/api/v1/articles/")
public Observable<CreateArticleResponse> createArticle(
@Part("article") Article article,
@Part("photo") TypedFile photo
);
Run Code Online (Sandbox Code Playgroud)
准备API并使用cURL成功测试.
$ 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"
Run Code Online (Sandbox Code Playgroud)
当我createArticle()从Android客户端发送数据时,我收到一个HTTP 400状态,指出字段是必需/缺失的.
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
Run Code Online (Sandbox Code Playgroud)
这是request.data在服务器端收到的内容:
ipdb> print request.data
<QueryDict: {u'article': [u'{"author":"me"}'], \
u'photo': [<TemporaryUploadedFile: IMG_1759215522.jpg \
(multipart/form-data)>]}>
Run Code Online (Sandbox Code Playgroud)
如何在多部分符合数据类型中转换Article对象?我读到Retrofit可能允许使用转换器.retrofit.mime.TypedOutput根据我对文档的理解,它应该是实现的东西.
多部分使用
RestAdapter转换器或者它们可以实现TypedOutput处理它们自己的序列化.
Ser*_*kyi 27
根据你的curl请求,你试图像这样创建smth:
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--
Run Code Online (Sandbox Code Playgroud)
使用改装适配器,可以通过下一个方式创建此请求:
@Multipart
@POST("/api/v1/articles/")
Observable<Response> uploadFile(@Part("author") TypedString authorString,
@Part("photo") TypedFile photoFile);
Run Code Online (Sandbox Code Playgroud)
用法:
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(<...>);
Run Code Online (Sandbox Code Playgroud)
这会产生类似的输出:
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--
Run Code Online (Sandbox Code Playgroud)
这里的关键区别在于您使用POJO Article article作为多部分参数,默认情况下将其转换Converter为json.而你的服务器需要普通的字符串.卷曲你发送cURL,而不是{"author":"cURL"}.
| 归档时间: |
|
| 查看次数: |
37244 次 |
| 最近记录: |