OkHttpResponse - 解析接收到的分块数据 text/html
OkHttpResponse - parse received chunked data which is text/html
我在解析来自服务器的分块响应时遇到问题。
这就是我使用 post.
创建请求(模拟表单提交)的方式
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 进行调试时,我没有看到 HTML 响应(响应选项卡为空),即使我得到 200 个成功的代码。
我猜我将不得不以某种方式读取块,也许是自定义拦截器或其他东西。任何人都可以给我一些关于如何 parse/read 响应来源的提示吗? - 谢谢!
一段时间后我自己想通了。基本上我必须做的是从源代码中读取块并解析它们,这些块是用 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
}
请记住,响应正文只能读取一次。根据方形文档参见以下内容:
Response bodies must be closed and may be consumed only once
此外,通过阅读文档,Square 建议关闭响应和正文,因为这可能会降低应用程序的速度。
我在解析来自服务器的分块响应时遇到问题。 这就是我使用 post.
创建请求(模拟表单提交)的方式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 进行调试时,我没有看到 HTML 响应(响应选项卡为空),即使我得到 200 个成功的代码。
我猜我将不得不以某种方式读取块,也许是自定义拦截器或其他东西。任何人都可以给我一些关于如何 parse/read 响应来源的提示吗? - 谢谢!
一段时间后我自己想通了。基本上我必须做的是从源代码中读取块并解析它们,这些块是用 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
}
请记住,响应正文只能读取一次。根据方形文档参见以下内容:
Response bodies must be closed and may be consumed only once
此外,通过阅读文档,Square 建议关闭响应和正文,因为这可能会降低应用程序的速度。