retrofit 2.0 使用之图片上传

xiaoxiao2021-02-28  140

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引用

[java] view plain copy print ? compile 'com.squareup.retrofit2:converter-gson:2.0.1'  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' 第二步,请求接口

[java] view plain copy print ? /**  * 数据请求服务  * 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);    }   /** * 数据请求服务 * 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); }

第三步,请求工具类

[java] view plain copy print ? /**  * 数据请求控制工具类  * 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);      }    }   /** * 数据请求控制工具类 * 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 注解

[java] view plain copy print ? /**  * 上传头像  */  @Multipart  @POST("/member/uploadMemberIcon.do")  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的形式传递参数

[java] view plain copy print ? /**  * 上传图片  * 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, "头像上传失败");          }      });  }   /** * 上传图片 * 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即可,如下:

[java] view plain copy print ? /**   * 上传图片   * 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, "头像上传失败");           }       });   }   /** * 上传图片 * 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一样道理

[java] view plain copy print ? /**    * 上传头像    */    @Multipart    @POST("/member/uploadMemberIcon.do")    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中添加

[java] view plain copy print ? /**  * 上传头像  */  public static Call<Result<String>> uploadMemberIcon(MultipartBody.Part part, RequestBody token) {      return ApiUtil.getApiService().uploadMemberIcon(part,token);  }   /** * 上传头像 */ public static Call<Result<String>> uploadMemberIcon(MultipartBody.Part part, RequestBody token) { return ApiUtil.getApiService().uploadMemberIcon(part,token); } 然后传参数

[java] view plain copy print ? 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, "头像上传失败");          }      });  }  
转载请注明原文地址: https://www.6miu.com/read-32010.html

最新回复(0)