retrofit 2.0 使用之图片上传

原文链接:http://blog.csdn.net/itjianghuxiaoxiong/article/details/52135748

        前段时间在新产品里开始使用retrofit 2.0作为数据请求框架,用起来的确好用的很,但由于网上文档杂乱,而且大都是2.0版本之前的文章,所以还是遇到不少坑的,最后发现还是官网github比较靠谱。一直想写篇博客mark一下也没时间,今天看到问答区有人和我遇到同样的问题,所以就总结分享一下图片上传。

权威资料:官网http://square.github.io/retrofit/  和github  https://github.com/square/retrofit

前期基本准备:

第一步,添加gradle引用

  1. compile 'com.squareup.retrofit2:converter-gson:2.0.1'  
  2. compile 'com.squareup.retrofit2:retrofit:2.0.1'  
    compile 'com.squareup.retrofit2:converter-gson:2.0.1'
    compile 'com.squareup.retrofit2:retrofit:2.0.1'
第二步,请求接口

  1. /** 
  2.  * 数据请求服务 
  3.  * create by malong at 2016/4/25 0:34 
  4.  */  
  5. public interface ApiService {  
  6.     /** 
  7.      * 上传头像 
  8.      */  
  9.     @Multipart  
  10.     @POST("/member/uploadMemberIcon.do")  
  11.     Call<Result<String>> uploadMemberIcon(@Part List<MultipartBody.Part> partList);  
  12.   
  13. }  
/**
 * 数据请求服务
 * create by malong at 2016/4/25 0:34
 */
public interface ApiService {
    /**
     * 上传头像
     */
    @Multipart
    @POST("/member/uploadMemberIcon.do")
    Call<Result<String>> uploadMemberIcon(@Part List<MultipartBody.Part> partList);

}


第三步,请求工具类

  1. /** 
  2.  * 数据请求控制工具类 
  3.  * create by malong at 2016/4/25 0:30 
  4.  */  
  5. public class ApiUtil {  
  6.     private static final String HOST = "http://www.update.test";//换成你上传用的服务器地址  
  7.     private static Retrofit retrofit;  
  8.     private static final int DEFAULT_TIMEOUT = 10;//超时时长,单位:秒  
  9.   
  10.     /** 
  11.      * 获取根服务地址 
  12.      */  
  13.     public static String getHOST() {  
  14.         return HOST;  
  15.     }  
  16.   
  17.     /** 
  18.      * 初始化 Retrofit 
  19.      */  
  20.     private static Retrofit getApiRetrofit() {  
  21.         if (retrofit == null) {  
  22.             OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();  
  23.             okHttpBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);  
  24.             retrofit = new Retrofit.Builder()  
  25.                     .client(okHttpBuilder.build())  
  26.                     .baseUrl(HOST)  
  27.                     .addConverterFactory(GsonConverterFactory.create())  
  28.                     .addCallAdapterFactory(RxJavaCallAdapterFactory.create())  
  29.                     .build();  
  30.         }  
  31.         return retrofit;  
  32.     }  
  33.   
  34.     /** 
  35.      * 创建数据请求服务 
  36.      */  
  37.     private static ApiService getApiService() {  
  38.         return ApiUtil.getApiRetrofit().create(ApiService.class);  
  39.     }  
  40.   
  41.     /** 
  42.      * 上传头像 
  43.      */  
  44.     public static Call<Result<String>> uploadMemberIcon(List<MultipartBody.Part> partList) {  
  45.         return ApiUtil.getApiService().uploadMemberIcon(partList);  
  46.     }  
  47.   
  48. }  
/**
 * 数据请求控制工具类
 * create by malong at 2016/4/25 0:30
 */
public class ApiUtil {
    private static final String HOST = "http://www.update.test";//换成你上传用的服务器地址
    private static Retrofit retrofit;
    private static final int DEFAULT_TIMEOUT = 10;//超时时长,单位:秒

    /**
     * 获取根服务地址
     */
    public static String getHOST() {
        return HOST;
    }

    /**
     * 初始化 Retrofit
     */
    private static Retrofit getApiRetrofit() {
        if (retrofit == null) {
            OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
            okHttpBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
            retrofit = new Retrofit.Builder()
                    .client(okHttpBuilder.build())
                    .baseUrl(HOST)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
        }
        return retrofit;
    }

    /**
     * 创建数据请求服务
     */
    private static ApiService getApiService() {
        return ApiUtil.getApiRetrofit().create(ApiService.class);
    }

    /**
     * 上传头像
     */
    public static Call<Result<String>> uploadMemberIcon(List<MultipartBody.Part> partList) {
        return ApiUtil.getApiService().uploadMemberIcon(partList);
    }

}

接下来是图片上传关键代码

方法一(推荐使用):

        在service添加请求方法,注意要使用@Multipart 和@POST 注解

  1. /** 
  2.  * 上传头像 
  3.  */  
  4. @Multipart  
  5. @POST("/member/uploadMemberIcon.do")  
  6. Call<Result<String>> uploadMemberIcon(@Part List<MultipartBody.Part> partList);  
    /**
     * 上传头像
     */
    @Multipart
    @POST("/member/uploadMemberIcon.do")
    Call<Result<String>> uploadMemberIcon(@Part List<MultipartBody.Part> partList);

通过MultipartBody.Part  list的形式传递参数

  1. /** 
  2.  * 上传图片 
  3.  * create by weiang at 2016/5/20 17:33. 
  4.  */  
  5. private void upLoad() {  
  6.     File file = new File(filePath);//filePath 图片地址  
  7.     String token = "ASDDSKKK19990SDDDSS";//用户token  
  8.     MultipartBody.Builder builder = new MultipartBody.Builder()  
  9.             .setType(MultipartBody.FORM)//表单类型  
  10.             .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类,即参数名  
  11.     RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);  
  12.     builder.addFormDataPart("imgfile", file.getName(), imageBody);//imgfile 后台接收图片流的参数名  
  13.   
  14.     List<MultipartBody.Part> parts = builder.build().parts();  
  15.     ApiUtil.uploadMemberIcon(parts).enqueue(new Callback<Result<String>>() {//返回结果  
  16.         @Override  
  17.         public void onResponse(Call<Result<String>> call, Response<Result<String>> response) {  
  18.             AppUtil.showToastInfo(context, response.body().getMsg());  
  19.         }  
  20.   
  21.         @Override  
  22.         public void onFailure(Call<Result<String>> call, Throwable t) {  
  23.             AppUtil.showToastInfo(context, "头像上传失败");  
  24.         }  
  25.     });  
  26. }  
    /**
     * 上传图片
     * create by weiang at 2016/5/20 17:33.
     */
    private void upLoad() {
        File file = new File(filePath);//filePath 图片地址
        String token = "ASDDSKKK19990SDDDSS";//用户token
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)//表单类型
                .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类,即参数名
        RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        builder.addFormDataPart("imgfile", file.getName(), imageBody);//imgfile 后台接收图片流的参数名

        List<MultipartBody.Part> parts = builder.build().parts();
        ApiUtil.uploadMemberIcon(parts).enqueue(new Callback<Result<String>>() {//返回结果
            @Override
            public void onResponse(Call<Result<String>> call, Response<Result<String>> response) {
                AppUtil.showToastInfo(context, response.body().getMsg());
            }

            @Override
            public void onFailure(Call<Result<String>> call, Throwable t) {
                AppUtil.showToastInfo(context, "头像上传失败");
            }
        });
    }

添加多个字符串参数,只需要在builder.addFormDataPart(key,value)的形式追加即可。多张图片上传只需要用for循环添加多个RequestBody即可,如下:

  1. /** 
  2.   * 上传图片 
  3.   * create by weiang at 2016/5/20 17:33. 
  4.   */  
  5.  private void upLoad() {  
  6.      List<String> pathList = getPathList();//此处是伪代码,获取多张待上传图片的地址列表  
  7.      String token = "ASDDSKKK19990SDDDSS";//用户token  
  8.      MultipartBody.Builder builder = new MultipartBody.Builder()  
  9.              .setType(MultipartBody.FORM)//表单类型  
  10.              .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类,即参数名  
  11.      //多张图片  
  12.      for (int i = 0; i < pathList.size(); i++) {  
  13.          File file = new File(pathList.get(i));//filePath 图片地址  
  14.          RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);  
  15.          builder.addFormDataPart("imgfile"+i, file.getName(), imageBody);//"imgfile"+i 后台接收图片流的参数名  
  16.      }  
  17.   
  18.      List<MultipartBody.Part> parts = builder.build().parts();  
  19.      ApiUtil.uploadMemberIcon(parts).enqueue(new Callback<Result<String>>() {//返回结果  
  20.          @Override  
  21.          public void onResponse(Call<Result<String>> call, Response<Result<String>> response) {  
  22.              AppUtil.showToastInfo(context, response.body().getMsg());  
  23.          }  
  24.   
  25.          @Override  
  26.          public void onFailure(Call<Result<String>> call, Throwable t) {  
  27.              AppUtil.showToastInfo(context, "头像上传失败");  
  28.          }  
  29.      });  
  30.  }  
   /**
     * 上传图片
     * create by weiang at 2016/5/20 17:33.
     */
    private void upLoad() {
        List<String> pathList = getPathList();//此处是伪代码,获取多张待上传图片的地址列表
        String token = "ASDDSKKK19990SDDDSS";//用户token
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)//表单类型
                .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类,即参数名
        //多张图片
        for (int i = 0; i < pathList.size(); i++) {
            File file = new File(pathList.get(i));//filePath 图片地址
            RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            builder.addFormDataPart("imgfile"+i, file.getName(), imageBody);//"imgfile"+i 后台接收图片流的参数名
        }

        List<MultipartBody.Part> parts = builder.build().parts();
        ApiUtil.uploadMemberIcon(parts).enqueue(new Callback<Result<String>>() {//返回结果
            @Override
            public void onResponse(Call<Result<String>> call, Response<Result<String>> response) {
                AppUtil.showToastInfo(context, response.body().getMsg());
            }

            @Override
            public void onFailure(Call<Result<String>> call, Throwable t) {
                AppUtil.showToastInfo(context, "头像上传失败");
            }
        });
    }

方法二:

评论里有同学问只传一张图片怎么传,其实方法一就可以啊,只不过list里只add一个图片就可以啦。当然也可以按如下方法做:

ApiService 中添加如下方法,其实就是单传一个MultipartBody.Part, 这种方式和方法一就像是Post请求中的@Field和@FieldMap一样道理

  1. /** 
  2.    * 上传头像 
  3.    */  
  4.   @Multipart  
  5.   @POST("/member/uploadMemberIcon.do")  
  6.   Call<Result<String>> uploadMemberIcon(@Part MultipartBody.Part part, @Part(ParamKey.TOKEN) RequestBody token);  
  /**
     * 上传头像
     */
    @Multipart
    @POST("/member/uploadMemberIcon.do")
    Call<Result<String>> uploadMemberIcon(@Part MultipartBody.Part part, @Part(ParamKey.TOKEN) RequestBody token);
在ApiUtil中添加

  1. /** 
  2.  * 上传头像 
  3.  */  
  4. public static Call<Result<String>> uploadMemberIcon(MultipartBody.Part part, RequestBody token) {  
  5.     return ApiUtil.getApiService().uploadMemberIcon(part,token);  
  6. }  
    /**
     * 上传头像
     */
    public static Call<Result<String>> uploadMemberIcon(MultipartBody.Part part, RequestBody token) {
        return ApiUtil.getApiService().uploadMemberIcon(part,token);
    }

然后传参数

  1. private void upLoad() {  
  2.     File file = new File(filePath);  
  3.     String token = AppUtil.getString(ConstantKey.USER_TOKEN, "");  
  4.     RequestBody tokenBody = RequestBody.create(MediaType.parse("text/plain"), token);  
  5.     RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);  
  6.     MultipartBody.Part imageBodyPart = MultipartBody.Part.createFormData("imgfile", file.getName(), imageBody);  
  7.   
  8.     ApiUtil.uploadMemberIcon(imageBodyPart,tokenBody).enqueue(new Callback<Result<String>>() {  
  9.         @Override  
  10.         public void onResponse(Call<Result<String>> call, Response<Result<String>> response) {  
  11.             AppUtil.showToastInfo(context, response.body().getMsg());  
  12.         }  
  13.   
  14.         @Override  
  15.         public void onFailure(Call<Result<String>> call, Throwable t) {  
  16.             AppUtil.showToastInfo(context, "头像上传失败");  
  17.         }  
  18.     });  
  19. }  
    private void upLoad() {
        File file = new File(filePath);
        String token = AppUtil.getString(ConstantKey.USER_TOKEN, "");
        RequestBody tokenBody = RequestBody.create(MediaType.parse("text/plain"), token);
        RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part imageBodyPart = MultipartBody.Part.createFormData("imgfile", file.getName(), imageBody);

        ApiUtil.uploadMemberIcon(imageBodyPart,tokenBody).enqueue(new Callback<Result<String>>() {
            @Override
            public void onResponse(Call<Result<String>> call, Response<Result<String>> response) {
                AppUtil.showToastInfo(context, response.body().getMsg());
            }

            @Override
            public void onFailure(Call<Result<String>> call, Throwable t) {
                AppUtil.showToastInfo(context, "头像上传失败");
            }
        });
    }











  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值