我使用的是retrofit2.0版本,在参考了网上的一些文章,终于调试好了图片上传,在这里记录一下,避免其他人走弯路。
retrofit2.0和retrofit2.1是不一样的,包名都已经不同了,大家注意下(我就被坑过了,主要还是我太小白,很多不懂)
下面开始说正事
1、gradle配置(如果你不用rxjava,可以无视掉)
retrofit2.0 gradle配置
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
2、我们先看下正常情况下上传图片是什么样的
使用postman工具,post提交一张图片,face是服务器指定的key值,针对每个人的项目来定(key=face,value=图片文件)
3、使用Fiddler抓包工具,查看正确的图片上传时,请求体是个什么样的。
name就是服务器定的key值,filename就是手机里图片的文件名。
4、android代码展示
接口定义
@Multipart
@POST("appapi-public-upImage?")
Observable>> changePortrait(@PartMap Map params);
Activity代码
File file = list.get(0);
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
Map params = new HashMap<>();
params.put("face; filename="+file.getName(), requestBody);
Retrofit retrofitInstance = AppRequest.getInstance().getRetrofitInstance();
ApiService apiService = retrofitInstance.create(ApiService.class);
apiService.changePortrait(params)
.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(uploadPicHttpResponse -> {
Log.e(TAG, "响应结果:" + uploadPicHttpResponse.t.get(0).toString());
parserJsonData(uploadPicHttpResponse.t.get(0));
});
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
这个image/png是mime类型,由于我上传的图片是png图片,所以就写成了这样,后面是图片的File对象(如果你上传的是jpg的图片,是否需要修改mime类型为image/jpeg或image/jpg,就需要大家去亲自测试了,这里起个抛砖引玉的作用,其实说白了就是懒,大家原谅我把)
params.put("face; filename="+file.getName(), requestBody);
这句代码就是拼接请求体的正文部分了,为了拼接成和抓包工具那种一模一样的请求体,我在参数拼接的时候,添加了一些“号。后面会贴出
抓包一看,这不对啊,和我们用postman模拟的请求体不太一样啊,正确格式应该是name=”xxxx“; filename="xxxx"
6、为了和postman请求体一样,修改了android代码如下
File file = list.get(0);
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
Map params = new HashMap<>();
params.put("face\"; filename=\""+file.getName(), requestBody);
Retrofit retrofitInstance = AppRequest.getInstance().getRetrofitInstance();
ApiService apiService = retrofitInstance.create(ApiService.class);
apiService.changePortrait(params)
.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(uploadPicHttpResponse -> {
Log.e(TAG, "响应结果:" + uploadPicHttpResponse.t.get(0).toString());
parserJsonData(uploadPicHttpResponse.t.get(0));
});
在face和filename那里,手动添加了引号。
7、再次通过手机上传图片,通过抓包工具抓包,查看请求体中的内容
我们发现已经和使用postman提交的请求体一模一样了,接口也正确返回了。
最后:本人技术一般,本文只是单纯的记录了整个调试成功的过程,文中如果有错误的地方,欢迎指出。