Retrofit 2 — How to Upload Files to Server
来源:互联网 发布:erp软件的前景 编辑:程序博客网 时间:2024/05/29 02:52
Retrofit 2 — How to Upload Files to Server
by Marcus Pöhls on November 02 2015, tagged in Android, Retrofit
The previous posts guided you through various use cases of Retrofit and showed you opportunities to enhance the app with Retrofit’s built-in functionality. This post will show you how to upload files to a backend server using the second major release of Retrofit, namely Retrofit 2.
The content of this post is based on Retrofit2.0.0-beta4
. We’ll update this post if future releases of Retrofit change the actual handling and interface definition process!Retrofit Series Overview
- Getting Started and Create an Android Client
- Basic Authentication on Android
- Token Authentication on Android
- OAuth on Android
- Multiple Query Parameters of Same Name
- Synchronous and Asynchronous Requests
- Send Objects in Request Body
- Define a Custom Response Converter
- Add Custom Request Header
- Optional Query Parameters
- How to Integrate XML Converter
- Using the Log Level to Debug Requests
- How to Upload Files to Server
- Series Round-Up
- Upgrade Guide from 1.9
- How to Upload Files to Server
- Log Requests and Responses
- Hawk Authentication on Android
- Simple Error Handling
- How to use OkHttp 3 with Retrofit 1
- Send Data Form-Urlencoded
- Manage Request Headers in OkHttp Interceptor
- How to Add Query Parameters to Every Request
- Add Multiple Query Parameter With QueryMap
- How to Use Dynamic Urls for Requests
- Url Handling, Resolution and Parsing
- Constant, Default and Logic Values for POST and PUT Requests
- How to Download Files from Server
- Cancel Requests
- Reuse and Analyze Requests
- How to Change API Base Url at Runtime
File Upload with Retrofit 1.x
We’ve already published a blog post on how to upload files using Retrofit 1.x
. If you’re using Retrofit 1, please follow the linked guide.
Using Retrofit 2? This guide is for you and please read on :)
Upload Files With Retrofit 2
This post is intentionally separated from the already published post on how to upload files with Retrofit v1, because the internal changes from Retrofit 1 to Retrofit 2 are profound and you need to understand the way Retrofit 2 handles file uploads.
Before we dive deeper into the file upload topic with Retrofit 2, let’s shortly recap the previously used functionality in v1. Retrofit 1 used a class called TypedFile
for file uploads to a server. This class has been removed from Retrofit 2. Further, Retrofit 2 now leverages the OkHttp library for any network operation and as a result OkHttp’s classes for use cases like file uploads.
Using Retrofit 2, you need to use OkHttp’s RequestBody
class and encapsulate your file into a request body. Let’s have a look at the interface definition for file uploads.
public interface FileUploadService { @Multipart @POST("/upload") Call<String> upload( @Part("myfile\"; filename=\"image.png\" ") RequestBody file, @Part("description") RequestBody description);}
You’re probably having a closer look at the content of the file’s @Part
annotation. Actually, there is an existing bug in OkHttp which requires this hacky workaround to get file uploads working using Retrofit 2.
Let me explain each part of the definition above and we’re starting with the annotation for file
. The first part myfile
is the name of the file which gets send to the server. Additionally, we need to hard-code the filename
so that your backend will recognize that there is a file as payload for further processing. The description
is just a string value wrapped within a RequestBody
instance. The description
part doesn’t require any workaround to be sent correctly as part of the payload.
Android Client Code
We’ve defined the necessary interface for Retrofit and now we can move on and touch the Android’s part to upload a file. We’ll use the ServiceGenerator
class which generates a service client. We’ve introduced theServiceGenerator
class within the getting started with Retrofit post earlier within this series.
FileUploadService service = ServiceGenerator.createService(FileUploadService.class);String descriptionString = "hello, this is description speaking"; RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString);File file = new File("path/to/your/file"); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);Call<String> call = service.upload(requestBody, description); call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.v("Upload", "success"); } @Override public void onFailure(Call<String> call, Throwable t) { Log.e("Upload", t.getMessage()); }});
The snippet above just shows you the code to initialize the payload (file
and description
) and how to use the file upload service. As already mentioned, the RequestBody
class is from OkHttp and used for file uploads. Its.create()
method requires two parameters: first, the media type which we parse from multipart/form-data
and second, the actual file. Then, we can pass the created request body as a parameter to the service interface and let Retrofit (in teamwork with OkHttp) handle the actual upload.
Remember the Content-Type
Please keep an eye on Retrofit’s content type. If you intercept the underlying OkHttp client and change the content type to application/json
, your server might have issues with the deserialization process. Make sure you’re not defining the header indicating you’re sending JSON data, but multipart/form-data
.
Exemplary Hapi Server for File Uploads
If you already have your backend project, you can lean on the example code below. We use a simple hapi server with a POST
route available at /upload
. Additionally, we tell hapi to don’t parse the incoming request, because we use a Node.js library called multiparty for the payload parsing.
Within the callback of multiparty’s parsing function, we’re logging each field to show its output.
method: 'POST', path: '/upload', config: { payload: { maxBytes: 209715200, output: 'stream', parse: false }, handler: function(request, reply) { var multiparty = require('multiparty'); var form = new multiparty.Form(); form.parse(request.payload, function(err, fields, files) { console.log(err); console.log(fields); console.log(files); return reply(util.inspect({fields: fields, files: files})); }); }}
Android client expects a return type of String
, we’re sending the received information as response. Of course your response will and should look different :)
Below you can see the output of a successful request and payload parsing. The first null
is the err
object. Afterwards, you can see the fields
which is only the description as part of the request. And last but not least, the file is available within the files
field. Here you see our previously defined names on client side. image
is passed as the original name and the actual field name is myfile
. For further processing, access the uploaded image at path
’s location.
Server Log for Parsed Payload
null { description: [ '"hello, this is description speaking"' ] }{ myfile: [ { fieldName: 'myfile', originalFilename: 'image.png" ', path: '/var/folders/rq/q_m4_21j3lqf1lw48fqttx_80000gn/T/ttzVoNPfBxMMirec1tJsnrd2.png', headers: [Object], size: 82745 } ] }
Outlook
File uploads are an essential feature within up-to-date apps and even though file uploads are kind of hacky with Retrofit 2, please keep in mind that the second major release is still in beta. We’re sure that this will be fixed until the final 2.0 release and everyone will be happy!
What to expect within the next post on Retrofit? Next week we’ll all about how to get back logging within Retrofit 2. Stay tuned, it will be a good shot!
Get Articles Directly to Your Inbox
Subscribe to receive a bi-weekly summary of our latest articles about
Android, Node.js, open source, and more!
- Retrofit 2 — How to Upload Files to Server
- How To Upload Files to the Internet Information Server
- How to Upload Large Files in PHP
- how to upload my project files to online svn host?
- How to upload your project to GitHub
- How to Upload Multiple files in one request along with other string parameters in android?
- Android:How to upload .mp3 file and image to http server?
- upload file to web server
- Android Upload File to Server
- Android Upload File to Server
- How to use TFTP to transfer files from develop board to your host server?
- How to create EPS files...
- How to Organize Your Files
- Retrofit upload files and text
- how to use automake to build files
- How To Upload An Image into BSP
- How to copy files from server to virtual machine in Windows 2012/2016
- how to delete .tmp file in server which is created during file upload
- 从100PV到1亿级PV网站架构演变
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- MVVM结合ReactiveCocoa在项目实践中的理解和总结的一些经验
- 网络爬虫-有道翻译
- 打开虚拟机时报硬盘UUID 已经存在的解决办法
- Retrofit 2 — How to Upload Files to Server
- Leetcode 62: Unique Paths
- HTML】Table边框使用总结 ,只显示你要显示的边框(内边框,外边框)
- crash处理case范例说明
- 安装office 2007 后,每次打开都要弹出一个 setup error 对话框
- 【CSS3】last-of-type选择器
- ScrollView头部悬停
- MYSQL千万级测试1亿数据的分页分析测试(顶)
- Vim 笔记