1. 演示
GIF 演示APK 蓝奏云
2. HTTP 报文格式
HTTP报文格式- 样例
GET
GET /api/timezone/Africa/Bissau HTTP/1.1
Host: worldtimeapi.org
- 样例
POST
POST /posts HTTP/1.1
Host: jsonplaceholder.typicode.com
Content-Type: application/json
Content-Length: 55
{
"title":"foo",
"body":"bar",
"userId":1
}
3. 使用Retrofit
请求网络数据
这里用
Kotlin
配合协程实现
class TestHttp {
companion object {
private val instance: Retrofit by lazy {
Retrofit.Builder().baseUrl("http://worldtimeapi.org/api/")
.addConverterFactory(GsonConverterFactory.create(Gson()))
.client(OkHttpClient.Builder().build())
}
val api: Api by lazy {
instance.create(Api::class.java)
}
}
}
3.1 GET
接口定义:
@GET("/timezone/africa/Abidjan")
suspend fun getWorldTimeGet()
发起请求:
TestHttp.api.getWorldTimeGet()
实际发送的数据:
http://worldtimeapi.org/api/timezone/africa/Abidjan
3.2 Path
只是在普通GET的基础上,可以定制url的path
接口定义:
@GET("/timezone/africa/{location}")
suspend fun getWorldTimeGetPath(@Path("location") path: String)
发起请求:
TestHttp.api.getWorldTimeGetPath("Abidjan")
实际发送的数据:
http://worldtimeapi.org/api/timezone/africa/Abidjan
3.3 Query
在url后追加参数
接口定义:
@GET("/timezone/africa/Abidjan")
suspend fun getWorldTimeGetQuery(@Query("location") location: String)
发起请求:
TestHttp.api.getWorldTimeGetQuery("Abidjan")
实际发送的数据:
http://worldtimeapi.org/api/timezone/africa/Abidjan?location=Abidjan
3.4 QueryMap
在url后追加多个参数;
JvmSuppressWildcards
注解是kotlin使用需要,具体参考hjkcghjmguyy老师的这篇文章
接口定义:
@GET("/timezone/africa/Abidjan")
suspend fun getWorldTimeGetQueryMap(@QueryMap map: Map<String,@JvmSuppressWildcards Any>)
发起请求:
TestHttp.api.getWorldTimeGetQueryMap(mapOf("location" to "Abidjan"))
实际发送的数据:
http://worldtimeapi.org/api/timezone/africa/Abidjan?location=Abidjan
3.5 POST
接口定义:
@POST("/timezone/africa/Abidjan")
suspend fun getWorldTimePost()
发起请求:
TestHttp.api.getWorldTimePost()
实际发送的数据:
http://worldtimeapi.org/api/timezone/afica/Abidjan
Content-Length: 0
3.6 Field
其实就是把
Query
的请求参数放到请求体中。
接口定义:
@FormUrlEncoded
@POST("/timezone/africa/Abidjan")
suspend fun getWorldTimePostField(@Field("location") location: String)
发起请求:
TestHttp.api.getWorldTimePostField("Abidjan")
实际发送的数据:
http://worldtimeapi.org/api/timezone/afica/Abidjan
Content-type: application/x-www-form-urlencoded
Content-Length: 16
location=Abidjan
3.7 FieldMap
其实就是把
QueryMap
的请求参数放到请求体中。
接口定义:
@FormUrlEncoded
@POST("/timezone/africa/Abidjan")
suspend fun getWorldTimePostFieldMap(@FieldMap location: Map<String,@JvmSuppressWildcards Any>)
发起请求:
TestHttp.api.getWorldTimePostFieldMap(
mapOf(
"location" to "Abidjan",
"path" to "Abidjan",
)
)
实际发送的数据:
http://worldtimeapi.org/api/timezone/afica/Abidjan
Content-type: application/x-www-form-urlencoded
Content-Length: 29
location=Abidjan&path=Abidjan
3.8 Body-Bean
Retrofit中做了转换,默认把传入的实体类或者对象转为Json格式的文本作为请求体。
接口定义:
@POST("/timezone/africa/Abidjan")
suspend fun getWorldTimePostBody(@Body location: Map<String,@JvmSuppressWildcards Any>)
发起请求:
TestHttp.api.getWorldTimePostBody(
mapOf(
"location" to "Abidjan",
"path" to "Abidjan",
)
)
实际发送的数据:
http://worldtimeapi.org/api/timezone/afica/Abidjan
Content-type: application/json; charset=UTF-8
Content-Length: 29
{"location"="Abidjan","path"="Abidjan"}
3.9 Body-RequestBody
这里相当于自己实现了实体转Json文本的过程,
fun String.toRequestBody(contentType: MediaType? = null): RequestBody
这个拓展方法是OKHTTP3
中的。
接口定义:
@POST("/timezone/africa/Abidjan")
suspend fun getWorldTimePostBody(@Body location: RequestBody)
发起请求:
private fun map2RequestBody(map: Map<String, Any>): RequestBody {
return Gson().toJson(map).toRequestBody("application/json".toMediaTypeOrNull())
}
TestHttp.api.getWorldTimePostBody(
map2RequestBody(
mapOf(
"location" to "Abidjan",
"path" to "Abidjan",
)
)
)
实际发送的数据:
http://worldtimeapi.org/api/timezone/afica/Abidjan
Content-type: application/json; charset=UTF-8
Content-Length: 29
{"location"="Abidjan","path"="Abidjan"}
3.10 Body-MultiRequestBody
多个请求体,比较特殊,一般是上传文件的时候用到,看具体接口。
接口定义:
@POST("/timezone/africa/Abidjan")
suspend fun getWorldTimePostMultiBody(@Body location: RequestBody)
发起请求:
TestHttp.api.getWorldTimePostMultiBody(
MultipartBody.Builder().addFormDataPart("location", "Abidjan")
.addFormDataPart("path", "Abidjan").build()
)
实际发送的数据:
http://worldtimeapi.org/timezone/africa/Abidjan Content-Type: multipart/mixed; boundary=1a6fa7f0-4401-4071-a92c-8eb404446f3b
Content-Length: 276
f0-4401-4071-a92c-8eb404446f3b
Content-Disposition: form-data; name="location"
Content-Length: 7
Abidjan
--1a6fa7f0-4401-4071-a92c-8eb404446f3b
Content-Disposition: form-data; name="path"
Content-Length: 7
Abidjan
--1a6fa7f0-4401-4071-a92c-8eb404446f3b--
网友评论