【網路】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裡面。