OkHttpResponse-解析接收的分块数据,它是text / html

问题描述 投票:0回答:1

我在解析来自服务器的分块响应时遇到问题。这就是我用帖子创建请求(模拟表单提交)的方式。

val requestBody = MultipartBody.Builder()
  .setType(MultipartBody.FORM)
  .addFormDataPart("key1","value1")
  .build()


val requestBuilder = Request.Builder()
  .url(formActionUrl)
  .method("POST",requestBody)
  .build()

val response = okHttpClient
                .newCall(requestBuilder)
                .execute()

对我来说,这里的问题是,当我尝试阅读正文来源时。

 if(isChunked){
   val responseBody = response.body
   val source = responseBody!!.source ()
   val buffer = Buffer () 
   val builder = java.lang.StringBuilder()
   while (!source.exhausted ()) {
      val readBytes = source.read (buffer, Long.MAX_VALUE)
      val data = buffer.readString (Charset.forName ("UTF-8"))
      builder.append(data)
   }
   Log.d("builder",builder.toString())
}

这正在记录一些字形。而且我无法获取HTML数据。

已调试:我试图用Postman复制确切的调用,并且我成功获取了HTML响应,但是,当我使用Stetho进行调试时,即使我获得了200个成功的代码,我也没有看到HTML响应(响应选项卡为空)。

我猜我将不得不以某种方式读取这些块,也许是自定义拦截器之类的东西。任何人都可以给我一些提示,说明如何从响应中解析/读取源代码吗? -谢谢!

android okhttp
1个回答
0
投票

过了一会儿,我自己弄清楚了。基本上,我要做的是从源中读取大块并解析使用Gzip编码的块(可以在响应头中找到编码-Content-Encoding)所以基本上这是代码:

   val isChunked = isChunked(response.headers)
   val subtype = responseBody.contentType()!!.subtype.toLowerCase() //html
   val type = responseBody.contentType()!!.type.toLowerCase() //text
   val charset = responseBody.contentType()!!.charset().toString()//UTF-8

   val buffer = Buffer()
   if(isChunked) {
      while (!source.exhausted()) {
         source.read(buffer, 8192)
      }
      source.close()
   }

   if(subtype.contains("html")) {
      val pureHtml = GZIPInputStream(buffer.inputStream())
         .bufferedReader(UTF_8)
         .use { it.readText() }
         buffer.flush()
      webview.loadData(pureHtml,"$type/$subtype",charset)
   }else{
      //handle diff types
   }

[请记住,响应正文只能读取一次。见下面的方形文档下面的波纹管:

响应主体必须关闭,并且只能食用一次

此外,从阅读文档开始,Square建议关闭响应和正文,因为这可能会减慢应用程序的速度。

© www.soinside.com 2019 - 2024. All rights reserved.