文件上传
Retrofit2本身是支持文件上传的, 但是由于当时的版本(Retrofit2 beta2)有一个小的bug, 需要用一个Hack来解决, 因此我就将以前写的ImageUploader稍微封装了一下.
由于之前的ImageUploader职责有写多, 同时包含了网络请求代码, 描述网络请求信息, 还有一些工具类代码. 因此我将其拆分成三个类:
- ImageUploader
只负责发送网络请求
- ImageUploadHelper
将请求结果转换成相应的实体, 将请求包装成Observable, 以及一些工具方法
- ImageUploadRequest
拼接请求, 如Url, 参数, 要上传的文件, 转换的实体类型等.虽然..类名叫ImageUploader, 但是也是可以用来上传文件的. 由于APP里绝大部分情况都是上传图片, 所以干脆就叫ImageUploader了. 接下来看看ImageUploader类, 此类只提供了一个公共方法, 一个接口, 以及一个异常类:
public class ImageUploader {
public void post(String actionUrl, Map<String, String> params,
Map<String, File> files, String fileKey, OnResponseListener listener);
public interface OnResponseListener {
void onResponse(String data);
void onError(Exception e);
}
class HttpException extends Exception {
private int httpCode;
private String message;
public HttpException(int httpCode, String message) {
this.httpCode = httpCode;
this.message = message;
}
public int getHttpCode() {
return httpCode;
}
public String getMessage() {
return message;
}
}
}post的具体实现就不贴出来了, 代码比较长, 主要是使用HttpURLConnection来上传文件. 传入post方法的参数在这里说明一下:
String actionUrl 请求的URL地址
Map params API接口所需的额外参数
Map files 待上传的文件
String fileKey 文件对应的键值, 如果此值为空, 则文件对应的键值默认为files的键, 如果不为空, 则键值全部为fileKey
OnResponseListener listener 上传结果的回调
OnResponseListener与HttpException都比较简单, 接下来看看ImageUploadRequest:
ImageUploadRequest类中包含有一个Builder类, 可以使用链式结构来拼接请求. 然后看看ImageUploadHelper
此类使用ImageUploader发送请求, 使用ImageUploadRequest类来拼接请求, 也就是说, 我们应该使用ImageUploadHelper类来上传文件而不是ImageUploader类. doPostWithObservable方法还将上传请求转换为Observable, 以便我们使用. 此处要注意的是, ImageUploadHelper后传入的泛型的类型, 要与ImageUploadRequest中的outputClass和innerClass一致, 不然会报转换错误. 如最终要解析的类型为BaseData<User>, 则泛型里需传入ImageUploadHelper<BaseData<User>>, 并且将ImageUploadRequest中的outputClass设置为BaseData.class, innerClass设置为User.class.
最终使用方法:
首先可以新建一个Model层的类:
然后就可以像一般的网络请求一样, 通过ResponseSubscriber来处理请求结果.
Last updated
Was this helpful?