apache-httpcomponents - Apache Http 异步客户端的内容 GZIP 解压缩
问题描述
在经典的HttpClient
GZIP 解压缩中,由ContentCompressionExec
. 这是如何完成的HttpAsyncClient
?我找不到任何AsyncExecChainHandler
实现此功能的东西。
解决方案
我最终AsyncResponseConsumer
在scala中实现了以下自己。
class SimpleDecompressingResponseConsumer(val entityConsumer: AsyncEntityConsumer[Array[Byte]])
extends AbstractAsyncResponseConsumer[SimpleHttpResponse, Array[Byte]](entityConsumer) {
override def informationResponse(response: HttpResponse, context: HttpContext): Unit = ()
override protected def buildResult(response: HttpResponse, entity: Array[Byte], contentType: ContentType): SimpleHttpResponse = {
val simpleResponse = SimpleHttpResponse.copy(response)
if (entity != null) simpleResponse.setBody(entity, contentType)
simpleResponse
}
}
class SimpleAsyncDecompressingEntityConsumer extends AbstractBinDataConsumer with AsyncEntityConsumer[Array[Byte]] {
@volatile
private var resultCallback: FutureCallback[Array[Byte]] = _
private var encoding: Array[Byte] => Array[Byte] = _
private var content: Array[Byte] = _
private val buffer = new ByteArrayBuffer(1024)
override def streamStart(entityDetails: EntityDetails, resultCallback: FutureCallback[Array[Byte]]): Unit = {
this.resultCallback = resultCallback
this.encoding = entityDetails.getContentEncoding match {
case "gzip" | "x-gzip" =>
bytes => IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(bytes)))
case "deflate" =>
bytes => IOUtils.toByteArray(new DeflateInputStream(new ByteArrayInputStream(bytes)))
case _ =>
identity
}
}
override def failed(cause: Exception): Unit = {
if (resultCallback != null) resultCallback.failed(cause)
releaseResources()
}
override def getContent: Array[Byte] = content
override def capacityIncrement(): Int = Int.MaxValue
override def data(src: ByteBuffer, endOfStream: Boolean): Unit = {
if (src == null) return
if (src.hasArray) buffer.append(src.array(), src.arrayOffset() + src.position(), src.remaining())
else while (src.hasRemaining) buffer.append(src.get)
}
override def completed(): Unit = {
this.content = encoding(buffer.toByteArray)
if (resultCallback != null) resultCallback.completed(content)
releaseResources()
}
override def releaseResources(): Unit = buffer.clear()
}
推荐阅读
- c - 如何在 C 中将元素添加到数组中?
- php - 如何将名字和姓氏作为键=>值添加到数组中并显示它们?
- javascript - 如何使用 Google 服务帐户和 Google API 来验证 G-Suite 用户的密码是否符合其用户 ID
- php - 根据用户输入 SQL 防止值为负数
- wordpress - 插件激活时,Wordpress 在表格中创建列
- python-3.x - 如何在熊猫数据框中为分类值进行分组最大行选择
- c++ - 什么时候可以用 const 装饰调用我的重载函数?
- python - UnboundLocalError, - 赋值前的引用
- c# - 当一个类使用泛型时,它是否是抽象的有关系吗?
- c++ - 如何让 Duktape 在 Mac 68k 上运行(就像在 PPC 上一样?)