胖蔡说技术
随便扯扯

OkHttp 请求的基本使用方法

OkHttp是目前App较为常用的一种网络请求框架,使用Okhttp请求数据内容可以有效的节省服务贷款,提升访问速度,目前OkHttp支持如下请求:

  • HTTP / 2支持允许对同一主机的所有请求共享一个套接字。
  • 连接池可减少请求延迟(如果HTTP / 2不可用)。
  • 透明的GZIP缩小了下载大小。
  • 响应缓存可以完全避免网络重复请求。

OkHttp的使用较为简单。他只是同步阻塞调用和异步方法回调。如下,通过示例来简单介绍如何用OkHttp来完成一次Get请求和Post请求操作(示例代码为Kotlin代码实现)。

GET 请求

Get请求可通过同步阻塞请求获取也可以通过异步方法回调获取,如下为这两种实现方式的实现示例代码:

  • 同步阻塞请求

同步阻塞可在当前代码块内获取,适用于直接获取返回数据的情景下:

private val client = OkHttpClient()
   fun run() {
     val request = Request.Builder()
         .url("https://publicobject.com/helloworld.txt")
         .build()

     client.newCall(request).execute().use { response ->
       if (!response.isSuccessful) throw IOException("Unexpected code $response")
       for ((name, value) in response.headers) {
         println("$name: $value")
       }

       println(response.body!!.string())
     }
   }
 
  • 异步方法回调

异步方法回调适用于监听类数据,可通过数据回调监听返回:

private val client = OkHttpClient()

   fun run() {
     val request = Request.Builder()
         .url("http://publicobject.com/helloworld.txt")
         .build()

     client.newCall(request).enqueue(object : Callback {
       override fun onFailure(call: Call, e: IOException) {
         e.printStackTrace()
       }

       override fun onResponse(call: Call, response: Response) {
         response.use {
           if (!response.isSuccessful) throw IOException("Unexpected code $response")

           for ((name, value) in response.headers) {
             println("$name: $value")
           }

           println(response.body!!.string())
         }
       }
     })
   }

 

POST请求

POST请求内容有很多种,一般常见的有如下:

  • 字符串(string)

字符串请求比较常见,也是我们用的最多的请求方式,一般有数据参数请求(header),和请求体字符串请求,请求类型有可能是text\json\markdown等,示例代码如下:

private val client = OkHttpClient()

   fun run() {
     val postBody = """
         |Releases
         |--------
         |
         | * _1.0_ May 6, 2013
         | * _1.1_ June 15, 2013
         | * _1.2_ August 11, 2013
         |""".trimMargin()

     val request = Request.Builder()
         .url("https://api.github.com/markdown/raw")
         .post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
         .build()

     client.newCall(request).execute().use { response ->
       if (!response.isSuccessful) throw IOException("Unexpected code $response")

       println(response.body!!.string())
     }
   }

   companion object {
     val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
   }

 

post请求需要在请求体内声明请求类型和编码方式。

  • 文件(file)

若是单独按类型而言的话,其实文件类型和流类型有重复部分,我们其实也可以通过将文件转换为流的方式进行请求传递,也可以将文件分成多块进行请求,如下:


 // 小文件传输
  private val client = OkHttpClient()

   fun run() {
     val file = File("README.md")

     val request = Request.Builder()
         .url("https://api.github.com/markdown/raw")
         .post(file.asRequestBody(MEDIA_TYPE_MARKDOWN))
         .build()

     client.newCall(request).execute().use { response ->
       if (!response.isSuccessful) throw IOException("Unexpected code $response")

       println(response.body!!.string())
     }
   }

   companion object {
     val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
   }


 
  • 流(streaming)

流的传输常见于文件传输,示例如下:

 private val client = OkHttpClient()

   fun run() {
     val requestBody = object : RequestBody() {
       override fun contentType() = MEDIA_TYPE_MARKDOWN

       override fun writeTo(sink: BufferedSink) {
         sink.writeUtf8("Numbers\n")
         sink.writeUtf8("-------\n")
         for (i in 2..997) {
           sink.writeUtf8(String.format(" * $i = ${factor(i)}\n"))
         }
       }

       private fun factor(n: Int): String {
         for (i in 2 until n) {
           val x = n / i
           if (x * i == n) return "${factor(x)} × $i"
         }
         return n.toString()
       }
     }

     val request = Request.Builder()
         .url("https://api.github.com/markdown/raw")
         .post(requestBody)
         .build()

     client.newCall(request).execute().use { response ->
       if (!response.isSuccessful) throw IOException("Unexpected code $response")

       println(response.body!!.string())
     }
   }

   companion object {
     val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
   }
 
  • 分段传输(multipart)

多段传输常见于传输文件(如图片、视频传输等),这对于文件的断点续传操作有很好的兼容


 private val client = OkHttpClient()

   fun run() {
     // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
     val requestBody = MultipartBody.Builder()
         .setType(MultipartBody.FORM)
         .addFormDataPart("title", "Square Logo")
         .addFormDataPart("image", "logo-square.png",
             File("docs/images/logo-square.png").asRequestBody(MEDIA_TYPE_PNG))
         .build()

     val request = Request.Builder()
         .header("Authorization", "Client-ID $IMGUR_CLIENT_ID")
         .url("https://api.imgur.com/3/image")
         .post(requestBody)
         .build()

     client.newCall(request).execute().use { response ->
       if (!response.isSuccessful) throw IOException("Unexpected code $response")

       println(response.body!!.string())
     }
   }

   companion object {
     /**
      * The imgur client ID for OkHttp recipes. If you're using imgur for anything other than running
      * these examples, please request your own client ID! https://api.imgur.com/oauth2
      */
     private val IMGUR_CLIENT_ID = "9199fdef135c122"
     private val MEDIA_TYPE_PNG = "image/png".toMediaType()
   }

 
  • 常见json 类型请求
public static final MediaType JSON
     = MediaType.get("application/json; charset=utf-8");

 OkHttpClient client = new OkHttpClient();

 String post(String url, String json) throws IOException {
   RequestBody body = RequestBody.create(json, JSON);
   Request request = new Request.Builder()
       .url(url)
       .post(body)
       .build();
   try (Response response = client.newCall(request).execute()) {
     return response.body().string();
   }
 }
 
赞(0) 打赏
转载请附上原文出处链接:胖蔡说技术 » OkHttp 请求的基本使用方法
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏