retrofit 2.0 使用之圖片上傳


        前段時間在新產品里開始使用retrofit 2.0作為數據請求框架,用起來的確好用的很,但由於網上文檔雜亂,而且大都是2.0版本之前的文章,所以還是遇到不少坑的,最后發現還是官網github比較靠譜。一直想寫篇博客mark一下也沒時間,今天看到問答區有人和我遇到同樣的問題,所以就總結分享一下圖片上傳。

權威資料:官網http://square.github.io/retrofit/  和github  https://github.com/square/retrofit

前期基本准備:

第一步,添加gradle引用

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

/**
 * 數據請求服務
 * 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: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 注解

    /**
     * 上傳頭像
     */
    @Multipart
    @POST("/member/uploadMemberIcon.do")
    Call<Result<String>> uploadMemberIcon(@Part List<MultipartBody.Part> partList);

通過MultipartBody.Part  list的形式傳遞參數

    /**
     * 上傳圖片
     * 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即可,如下:

   /**
     * 上傳圖片
     * 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一樣道理

  /**
     * 上傳頭像
     */
    @Multipart
    @POST("/member/uploadMemberIcon.do")
    Call<Result<String>> uploadMemberIcon(@Part MultipartBody.Part part, @Part(ParamKey.TOKEN) RequestBody token);
在ApiUtil中添加

    /**
     * 上傳頭像
     */
    public static Call<Result<String>> uploadMemberIcon(MultipartBody.Part part, RequestBody token) {
        return ApiUtil.getApiService().uploadMemberIcon(part,token);
    }

然后傳參數

    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, "頭像上傳失敗");
            }
        });
    }












注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com