項目中遇上了服務器請求 form-data 發現寫法有很多,這裏我僅僅是用來發送鍵值對,並沒有發送文件。並且使用的是okHttp4 其中RequestBody創建方式與原來okHttp3中略有不同。
第一種方式
使用 MultipartBody
創建RequestBody
。實際上MultipartBody
繼承了RequestBody
擴展,專門用來發送form數據的。這個時候就不用使用 @Multipart
來註解了。
api部分
@POST("/plant/showData.php")
fun getPant(@Body requestBody: RequestBody): Call<Any>// 可以換成RxJava的Observable
使用,假設已經創建對應api
val requestBody: RequestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("action", "getPlant")
.build()
val call = api.getPant(requestBody)
call.enqueue(/*省略回調*/)
這種方式呢,在api接口中不用配置那麼複雜,所有鍵值對可以通過addFormDataPart方法來添加。
第二種方式@Multipart + @Part
api部分,每個@part對應一個鍵值對,這裏我的鍵名是action(後臺給的我也沒辦法)
@Multipart
@POST("/plant/showData.php")
fun getProcess(@Part("action") requestBody: RequestBody):Call<Any>
使用方式,順便用用coroutines
//關鍵body的創建方式,getProcess是要發送的值,這是okHttp4種RequestBody的創建方式
val body = "getProcess".toRequestBody("text/plain".toMediaType())
//下面是用來異步發送請求的,可以用你喜歡的異步方式
launch {
var response: Response<Any>? = null
withContext(Dispatchers.IO) {
response = api.getProcess(body).execute()
}
Log.d(TAG, response!!.body().toString())
}
第三種方式 @Multipart + @PartMap
這種方式和上面那個一樣,只不過如果鍵值對太多,就需要使用多個@Part那還不如傳遞個Map進去呢。
api部分,注意Map最好選擇MutableMap,否則會有異常出現。
@Multipart
@POST("/plant/showData.php")
fun getProcess(@PartMap requestMap: MutableMap<String, RequestBody>): Call<Any>
使用方式
val body = "getProcess".toRequestBody("text/plain".toMediaType())
val requestMap = mutableMapOf<String, RequestBody>()
requestMap["action"] = body
launch {
val deferred = async(Dispatchers.IO){
api.getProcess(requestMap).execute()
}
val response: Response<Any>? = deferred.await()
Log.d(TAG, response!!.body().toString())
}