美文网首页
Retrofit网络请求示例及根本请求内容

Retrofit网络请求示例及根本请求内容

作者: 小强开学前 | 来源:发表于2020-12-03 16:46 被阅读0次

    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--
    

    相关文章

      网友评论

          本文标题:Retrofit网络请求示例及根本请求内容

          本文链接:https://www.haomeiwen.com/subject/hxymwktx.html