How to send multipart/form-data with Retrofit?

后端 未结 2 1835
耶瑟儿~
耶瑟儿~ 2020-12-05 02:48

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         


        
相关标签:
2条回答
  • 2020-12-05 02:56

    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);
    

    Usage:

    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--
    

    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"}.

    0 讨论(0)
  • The server expects an "author" string but you're trying to pass it an "article" object. Pass it "String author" instead of "Article article."

    Also, I think the "no file submitted" error is a red herring because the file is clearly present in your "request.data."

    0 讨论(0)
提交回复
热议问题