Retrofit 2.0 轻松实现多文件/图片上传
2016-10-19 17:12
579 查看
使用 Retrofit1.x上传文件
大家都知道在2.0以前版本上传图片的姿势public interface ApiManager { @Multipart @POST("/user/addCarInfo") void addCarInfo(@QueryMap Map<String, Object> options, @Part("file") TypedFile file, Callback<JsonElement> response); }
使用 Retrofit 2.X 上传
Retrofit 2上传文件使用2,0,我们发现TypedFile类型被私有化了 ,无法继续使用1.9的传方式无法再上层调用了,可以MultipartBody.Part代替
public interface FileUploadService { @Multipart @POST("upload") Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file); }
具体用法。
// 创建 RequestBody,用于封装 请求RequestBody RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); // MultipartBody.Part is used to send also the actual file name MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile); // 添加描述 String descriptionString = "hello, 这是文件描述"; RequestBody description = RequestBody.create( MediaType.parse("multipart/form-data"), descriptionString); // 执行请求 Call<ResponseBody> call = service.upload(description, body); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.v("Upload", "success"); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.e("Upload error:", t.getMessage()); } });
}
上报一张图片
@Multipart @POST("you methd url upload/") Call<ResponseBody> uploadFile( @Part("avatar\\\\"; filename=\\\\"avatar.jpg") RequestBody file);
上报多张图片
@POST("upload/") Call<ResponseBody> uploadFiles(@Part("filename") String description, @Part("pic\\\\"; filename=\\\\"image1.png") RequestBody imgs1, @Part("pic\\\\"; filename=\\\\"image2.png") RequestBody imgs2, @Part("pic\\\\"; filename=\\\\"image3.png") RequestBody imgs3, @Part("pic\\\\"; filename=\\\\"image4.png") RequestBody imgs4);
图片和字符串同时上报
@Multipart @POST("upload/") Call<ResponseBody> register( @Query("name") String cardName, @Query("phone") String callphone, @Query("address") String address, @Part("avatar\\\\"; filename=\\\\"avatar.jpg") RequestBody avatar, );
此种方式让你很好的解决用户注册问题。包含用户全部信息
上面的代码片段中显示的代码初始化(RequestBody 和description),以及如何使用文件上传服务。正如已经提到的,从OkHttp RequestBody类用于描述。需要两个RequestBody.create()方法
除了描述,必须将添加文件包装成MultipartBody的实例。这就是你需要使用适当的从客户端上传文件。此外,您可以添加createFormData中的uploadFile(Uri fileUri)方法和重用
设置 Content-Type
请注意设置的内容类型。如果你拦截底层OkHttp客户机和更改内容类型application / json, 你的服务器可能反序列化过程出现的问题。请确保你没有自定义multipart/form-dataupLoad图片也可以具体指明Content-Type 为 “image/jpg”格式的
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), mFile);
上传文件到服务端示例
如果你已经有你的后端项目, 您可以依靠下面的示例代码。我们使用一个简单api 上传服务器。此外我们告诉api 传入参数的请求,因为我们使用的是Node.js解析的回调函数,我们记录每个字段来显示其输出。
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})); }); }}
安卓客户端收到返回类型的字符串, 我们将接收到的上传成功的状态的回调。当然你可以处理也可以不处理。
下面你将看到一个成功的请求的输出端和有效载荷的解析。第一个空对象。之后,你可以看到字段只描述作为请求的一部分。接着可以收到文件描述,文件大小,文件昵称和保存路径。
服务器解析有效数据的日志
Null { description: [ 'hello, this is description speaking' ] } { picture: [ { fieldName: 'picture', originalFilename: '20160312_095248.jpg', path: '/var/folders/rq/q_m4_21j3lqf1lw48fqttx_80000gn/T/X_sxX6LDUMBcuUcUGDMBKc2T.jpg', headers: [Object], size: 39369 } ] }
回顾
文件上传是最新的应用程序中必不可少的功能,你可以将此功能集成在您的应用程序使用翻新。本文指导您完成你的Android设备上报文件到您的后端服务器的第一个 步骤。上传出现类型错误解决方案:
其中一定要添加上filename这个
public interface CheckIn { @Multipart @POST("/check/checkin.action") Call<ResponseCode> checkIn(@Part("image\"; filename=\"文件名.jpg") RequestBody file); }
创建RequestBody对象作为参数上传
RequestBody imgFile = RequestBody.create(MediaType.parse("image/*"), imgFile);
以上方法解决了文件正常上传的问题,但是文件名却只能是常量,固定死了,并不是理想的结果,那么接下来就是解决这个问题。
首先是不需要在interface上定义文件名,而是通过Map来上传所有参数。
参数定义如下:
try { Staff staff = (Staff) SharedPreferencesUtils.getObject(context,LoginActivity.LOGIN_USER); RequestBody staffPhone = RequestBody.create(MediaType.parse("text/plain"), staff.getPhone()); RequestBody time = RequestBody.create(MediaType.parse("text/plain"), "时间"); RequestBody address = RequestBody.create(MediaType.parse("text/plain"), "地点"); RequestBody type = RequestBody.create(MediaType.parse("text/plain"), "类型"); Map<String, RequestBody> map = new HashMap<>(); map.put("staffPhone",staffPhone); map.put("checkTime",time); map.put("checkAddress",address); map.put("checkType",type); if (imgFile != null) { RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), imgFile); map.put("image\"; filename=\""+imgFile.getName()+"", fileBody); } HttpService.checkIn(map); } catch (IOException e) { e.printStackTrace(); }
interface如下:
public interface CheckIn{ @Multipart @POST("/check/checkin.action") Call<ResponseCode> checkIn(@PartMap Map<String, RequestBody> params); }
OK,搞定。
文/Tamic(简书作者)
原文链接:http://www.jianshu.com/p/acfefb0a204f
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
相关文章推荐
- Retrofit 2.0 超能实践(三),轻松实现多文件/图片上传/Json字符串/表单
- Retrofit 2.0 超能实践(三),轻松实现文件/多图片上传/Json字符串
- Retrofit 2.0 超能实践(三),轻松实现多文件/图片上传/Json字符串/表单
- Retrofit 2.0 超能实践(三),轻松实现文件/图片上传
- Retrofit 2.0 轻松实现文件/多图片上传/Json字符串
- Retrofit 2.0 超能实践(三),轻松实现文件/多图片上传/Json字符串
- Retrofit2.0轻松实现上传
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(七) 之 历史记录查询(时间,关键字,图片,文件),关键字高亮显示。
- 安卓学习笔记---Retrofit2.0 实现图文(参数+图片)上传方法总结
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(三) 之 实现单聊,群聊,发送图片,文件。
- Retrofit2.0 实现图文(参数+图片)上传方法总结
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传
- Android Retrofit2.0实现文件上传和下载
- Android Retrofit实现多图片/文件、图文上传功能
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传
- Asp.net 2.0 用 FileUpload 控件实现多文件上传 用户控件(示例代码下载)
- asp下轻松实现将上传图片到数据库的代码
- asp下轻松实现将上传图片到数据库的代码