1. 程式人生 > >【網路】Retrofit2 POST(引數傳遞和檔案上傳)

【網路】Retrofit2 POST(引數傳遞和檔案上傳)

tjstudy: 寫在前面
環境 :android 2.1.1,Retrofit2

個人使用總結

1、 匯入Retrofit 所需要的包

compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'

這裡推薦一個很好用的列印log的工具—KLOG
匯入包:

compile 'com.github.zhaokaiqiang.klog:library:1.5.0'

2、 網路訪問介面類APIService

  • 1、普通的post引數
  • 2、上傳檔案 這種方式指定陣列名為file,檔名是test.png,不方便使用。 多檔案上傳,使用 @PartMap Map<String, RequestBody> params 要注意在設定每一個RequestBody檔案的時候,陣列名不能一致,否則會覆 蓋。
  • 3、上傳單檔案
  • 4、上傳多檔案
  • 5、上傳檔案和引數 引數也需要封裝成MultipartBody.Part這樣的型別,不然傳遞會出錯,這個型別其實就是將這些資料封裝成表單的型別,因為在這裡不能使用FormUrlEncoded進行處理
/**
 * 網路訪問介面
 */
public interface APIService {
    //1、
    @FormUrlEncoded
    @POST("test.php")
    Observable<ResponseBody> login(
            @Field("no") String no,
            @Field
("pass") String pass); //2、 @Multipart @POST("upload.php") Observable<ResponseBody> uploadFile( @Part("file\"; filename=\"test.png") RequestBody file ); //3、 @Multipart @POST("upload.php") Observable<ResponseBody> uploadFile( @Part MultipartBody.Part file ); //4、 @Multipart @POST("upload.php") Observable<ResponseBody> uploadFile( @Part() List<MultipartBody.Part> files ); //5、 @Multipart @POST("upload.php") Observable<ResponseBody> uploadFile( @Part() List<MultipartBody.Part > files ); }

MultipartBody是okhttp3的一個方法,在okhttp2裡面不存在。

3、 Post 方式說明

方式1 只需要對應的傳入String就可以了,方式2 忽略
其他的,則需要經過MultipartBody.part的封裝
MultipartBody.part的封裝

  • 1) 對檔案的封裝:
File file = new File(Environment.getExternalStorageDirectory()
            .getAbsolutePath() + "/Pictures/test111.png");
RequestBody requestBody =
            RequestBody.create(MediaType.parse("image/png"), file);
//引數1 陣列名,引數2 檔名。
MultipartBody.Part photo1part = 
            MultipartBody.Part.createFormData("pic1", "pic2", requestBody1);

php收到的資料如下圖:

這裡寫圖片描述

上傳多個檔案,則會有多個這樣的陣列

  • 2) 對引數的封裝:
MultipartBody.Part no = 
            MultipartBody.Part.createFormData("name", “tjstudy”);

4、 方式1轉變為MultipartBody.Part方式

可以理解為,MultipartBody.part是為了將引數封裝為表單的樣式。

@Multipart
@POST("test.php")
Observable<ResponseBody> login(
        @Part MultipartBody.Part no,
        @Part MultipartBody.Part pass);
MultipartBody.Part no = 
        MultipartBody.Part.createFormData("name", “tjstudy”);
MultipartBody.Part pass =
        MultipartBody.Part.createFormData("pass", “123456”);

之後進行網路訪問,呼叫網路接口裡面對應的方法就可以了(上面的這個login方法)

5、 又踩坑了(檔案和引數一起上傳)

  • 1) 引數上傳:

    使用@Part(”no”)String no 訪問網路,伺服器端收到了這樣的資料
    “no”=””12345”” 多了一對引號
    —–後使用,MultipartBody.Part,解決了問題

  • 2) 引數上傳:

網上的另外一種方式,在post方式裡面使用
@Query(”no”)String no
什麼都沒有上傳成功,根本沒有訪問到網路
—-猜測,Query是Get方式的訪問方式,應該是不會成功的。網上的少數部落格也存在坑。

  • 3) 多檔案上傳-只上傳了一個

Retrofit上傳的時候,會將相關資訊放到一個數組裡面,只要陣列名一樣,就會存在檔案被覆蓋,只上傳了一個檔案。檔案的上傳,並不是像我理解的,是將一組檔案存在一個json資料裡面,每一個檔案再以單獨的一個物件存在。
檔案,陣列名不能一樣

6、使用總結

在只需要傳遞引數的時候,直接使用方式1(@FormUrlEncoded@Field(“no”) String no)就可以了,只要涉及到要上傳檔案,則需要使用@Multipart作為標記,並且要上傳的檔案和引數都需要封裝到MultipartBody.part裡面。