Retrofit 2.0 超能實踐(三),輕鬆實現文件/多圖片上傳/Json字符串

文:http://blog.csdn.net/sk719887916/article/details/51755427
Tamic 簡書&csdn同步 獲取技術文章請關注底部微信公衆號!

通過前兩篇姿勢的入門

本文出自:http://blog.csdn.net/sk719887916/article/details/51755427 碼小白

通過對Retrofit2.0的前兩篇的基礎入門和案例實踐,掌握了怎麼樣使用Retrofit訪問網絡,加入自定義header,包括加入SSL證書,基本的調試基礎,coolkie同步,但很多需求需要文件的上傳,今天主題就來分享怎麼用Retrofit2.0 上傳文件和圖片。


使用 Retrofit1.x上傳文件

大家都知道在2.0以前版本上傳圖片的姿勢

 public interface ApiManager {
    @Multipart
    @POST("/user/addCarInfo")
    void addCarInfo(@QueryMap Map<String, Object> options, @Part("file") TypedFile file, Callback<JsonElement> response);

}

使用 Retrofit 2.X 上傳

Retrofit 2上傳文件

使用2,0,我們發現TypedFile類型被私有化了 ,無法繼續使用1.9的傳方式無法再上層調用了,可以MultipartBody.Part代替

 public interface FileUploadService {  
 @Multipart
 @POST("upload")
 Call<ResponseBody> upload(@Part("description") RequestBody description,
                          @Part MultipartBody.Part file);
}

具體用法

// 創建 RequestBody,用於封裝 請求RequestBody
RequestBody requestFile =
        RequestBody.create(MediaType.parse("multipart/form-data"), file);

// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
        MultipartBody.Part.createFormData("image", file.getName(), requestFile);

// 添加描述
String descriptionString = "hello, 這是文件描述";
RequestBody description =
        RequestBody.create(
                MediaType.parse("multipart/form-data"), descriptionString);

// 執行請求
Call<ResponseBody> call = service.upload(description, body);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call,
                           Response<ResponseBody> response) {
        Log.v("Upload", "success");
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        Log.e("Upload error:", t.getMessage());
    }
});

}

上報一張圖片

@Multipart
 @POST("you methd url upload/")
Call<ResponseBody> uploadFile(
        @Part("avatar\\\\"; filename=\\\\"avatar.jpg") RequestBody file);

上報多張圖片

@POST("upload/")
Call<ResponseBody> uploadFiles(@Part("filename") String description,
                                     @Part("pic\\\\"; filename=\\\\"image1.png") RequestBody imgs1,
                                     @Part("pic\\\\"; filename=\\\\"image2.png") RequestBody imgs2,
                                     @Part("pic\\\\"; filename=\\\\"image3.png") RequestBody imgs3,
                                     @Part("pic\\\\"; filename=\\\\"image4.png") RequestBody imgs4);

如果圖片數量不確定

  @Multipart
@POST("{url}")
Observable<ResponseBody> uploadFiles(
        @Path("url") String url,
        @Part("filename") String description,
        @PartMap() Map<String, RequestBody> maps);

或者:

@Multipart
@POST("{url}")
Observable<ResponseBody> uploads(
        @Path("url") String url,
        @Part("description") RequestBody description,
        @Part("filekey") MultipartBody.Part file);

圖片和參數同時上報

  @Multipart
@POST("upload/")
Call<ResponseBody> register(
                                   
                                   @QueryMap Map<String , String> usermaps,
                                   @Part("avatar\\\\"; filename=\\\\"avatar.jpg") RequestBody avatar,
                                   );

此種方式讓你很好的解決用戶註冊問題。包含用戶全部信息

上面的代碼片段中顯示的代碼初始化(RequestBody 和description),以及如何使用文件上傳服務。正如已經提到的,從OkHttp RequestBody類用於描述。需要兩個RequestBody.create()方法

除了描述,必須將添加文件包裝成MultipartBody的實例。這就是你需要使用適當的從客戶端上傳文件。此外,您可以添加createFormData中的uploadFile(Uri fileUri)方法和重用

設置 Content-Type

請注意設置的內容類型。如果你攔截底層OkHttp客戶機和更改內容類型application / json, 你的服務器可能反序列化過程出現的問題。請確保你沒有自定義multipart/form-data

upLoad圖片也可以具體指明Content-Type 爲 “image/jpg”格式的

   RequestBody requestFile =
            RequestBody.create(MediaType.parse("image/jpg"), mFile);

還有常用的:

上傳Json

@POST("/uploadJson")
Observable<ResponseBody> uploadjson(
        @Body RequestBody jsonBody);

upLoadJson 也可以具體指明Content-Type 爲 “application/json”格式的

具體組裝我們的RequestBody則可以這樣:

 RequestBody body= 
               RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), jsonString);

接着可以這樣調用:

// 執行請求
Call<ResponseBody> call = service.uploadJson(description, body);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call,
                           Response<ResponseBody> response) {
        Log.v("Upload", "success");
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        Log.e("Upload error:", t.getMessage());
    }
});

}

至於服務器返回什麼類型的model, 開發者可以自定義 譬如你可以把APi 中的 ResponseBody 指定爲你自己的javaBean,當然上層構建Callback的時候也必須是 Call<MyBean>

@POST("/uploadJson")
Observable<MyBean> uploadjson(
        @Body RequestBody jsonBody);

上傳文件到服務端示例

如果你已經有你的後端項目, 您可以依靠下面的示例代碼。我們使用一個簡單api 上傳服務器。此外我們告訴api 傳入參數的請求,因爲我們使用的是Node.js

解析的回調函數,我們記錄每個字段來顯示其輸出。

method: 'POST', 
 path: '/upload',  
config: {  
payload: {
    maxBytes: 209715200,
    output: 'stream',
    parse: false
},
handler: function(request, reply) {
    var multiparty = require('multiparty');
    var form = new multiparty.Form();
    form.parse(request.payload, function(err, fields, files) {
        console.log(err);
        console.log(fields);
        console.log(files);

        return reply(util.inspect({fields: fields, files: files}));
    });
}}

安卓客戶端收到返回類型的字符串, 我們將接收到的上傳成功的狀態的回調。當然你可以處理也可以不處理。
下面你將看到一個成功的請求的輸出端和有效載荷的解析。第一個空對象。之後,你可以看到字段只描述作爲請求的一部分。接着可以收到文件描述,文件大小,文件暱稱和保存路徑。

服務器解析有效數據的日誌

   Null
  { description: [ 'hello, this is description speaking' ] }
{ picture:
  [ { fieldName: 'picture',
    originalFilename: '20160312_095248.jpg',
    path:      '/var/folders/rq/q_m4_21j3lqf1lw48fqttx_80000gn/T/X_sxX6LDUMBcuUcUGDMBKc2T.jpg',
   headers: [Object],
   size: 39369 } ] }

回顧

文件上傳是最新的應用程序中必不可少的功能,你可以將此功能集成在您的應用程序使用翻新。本文指導您完成你的Android設備上報文件到您的後端服務器的第一個步驟。

源碼:https://github.com/Tamicer/Novate

Retrofit 2.0系列請閱讀簡書
更多技術文章請關注碼小白

Retrofit 2.0系列請閱讀

第一時間獲取技術文章請關注微信公衆號!

開發者技術前線

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章