retrofit2.0,上传图片

我使用的是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'

retrofit2.1的gradle配置(大家区分好,你要用的retrofit2.1,就去网上搜,很多的,如果和我一样用的retrofit2.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抓包工具,查看正确的图片上传时,请求体是个什么样的。

retrofit2.0,上传图片_第1张图片

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);
这句代码就是拼接请求体的正文部分了,为了拼接成和抓包工具那种一模一样的请求体,我在参数拼接的时候,添加了一些“号。后面会贴出


5、手机连接上Fiddler,从手机上进行图片上传,抓包查看请求体是否正确

retrofit2.0,上传图片_第2张图片

抓包一看,这不对啊,和我们用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、再次通过手机上传图片,通过抓包工具抓包,查看请求体中的内容

retrofit2.0,上传图片_第3张图片

我们发现已经和使用postman提交的请求体一模一样了,接口也正确返回了。



最后:本人技术一般,本文只是单纯的记录了整个调试成功的过程,文中如果有错误的地方,欢迎指出。


你可能感兴趣的:(retrofit)