当前位置: 首页 > 知识库问答 >
问题:

使用Spring WebClient解码内容编码gzip

易博文
2023-03-14

我正在使用Spring WebClient(Spring 5.1.3)调用一个web服务。服务以内容类型:application/json内容编码:gzip

ClientResponse。bodyToMono然后失败,出现错误“JSON解码错误:非法字符((CTRL-CHAR,代码31)),我认为这是因为在尝试解析JSON之前,内容尚未解码。

下面是我如何创建WebClient的代码片段(简化)

HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();

然后我使用WebClient进行调用:

webClient.get().uri(uri)
    .accept(MediaType.APPLICATION_JSON)
    .header(HttpHeaders.ACCEPT_ENCODING, "gzip")
    .exchange()

HTTP请求有两个标头:

Accept: application/json
Accept-Encoding: gzip

响应包含以下标题:

set-cookie: xxx
content-type: application/json; charset=utf-8
content-length: 1175
content-encoding: gzip
cache-control: no-store, no-cache

通过执行以下操作,我能够手动解码GZIP内容,并从结果中获取有效的JSON

webClient.get().uri(uri)
        .accept(MediaType.APPLICATION_JSON)
        .header("accept-encoding", "gzip")
        .exchange()
        .flatMap(encodedResponse -> encodedResponse.body((inputMessage, context) ->
                inputMessage.getBody().flatMap(dataBuffer -> {
                    ClientResponse.Builder decodedResponse = ClientResponse.from(encodedResponse);
                    try {
                        GZIPInputStream gz = new GZIPInputStream(dataBuffer.asInputStream());
                        decodedResponse.body(new String(gz.readAllBytes()));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    decodedResponse.headers(headers -> {
                        headers.remove("content-encoding");
                    });
                    return Mono.just(decodedResponse.build());
                }).flatMap(clientResponse -> clientResponse.bodyToMono(Map.class))

共有1个答案

谷梁俊楚
2023-03-14

此功能由Reactornetty客户端原生支持。

你应该像这样创建HttpClient

HttpClient httpClient = HttpClient.create()
             .secure(sslContextSpec -> sslContextSpec.sslContext(sslContext))
             .compress(true);

这样就不需要添加accept encoding请求头,因为它已经为您完成了。

请注意,当您不提供自定义HttpClient实例时,此位由连接器本身完成。

 类似资料:
  • 当我向请求添加accept编码头时。 垂直方向。x-WebClient/3.9.5忽略此标头,并且我从服务器收到的响应没有“内容编码”标头选项。 相反,它的标题为“传输编码”:“分块”。 如何传递accept encoding=gzip并用Vert解压缩从服务器得到的响应。x-WebClient/3.9.5

  • 我必须解密一些数据发送到我的网站,使用aes-128-gcm加密与JAVA密码。 我想知道这是否与我必须对二进制数据进行的字符串操作有关,或者提供者没有给我所需的所有必要信息。 我也不知道解密数据必须使用的Tag_length是什么。提供程序还告诉我IV_Length是16个字符长,但是当我使用openssl_cipher_iv_length('aes-128-gcm')时,它建议是12个字符。

  • 问题内容: 我有一个用于ERP系统的快速开发工具,该工具仅允许使用vbscript。我正在尝试使用VBS创建一个简单的AJAX请求。可以使用“ Microsoft.XMLHTTP”对象。 下一步是使用json从网络服务器接收数据。但是在VBS中似乎没有像“ json_decode”或其他功能。 有人知道解决方案吗?还是开发自己的json函数的唯一选择? 问题答案: 由于JSON是一种分层数据格式,

  • 我试图防止CRLF注入(在用户输入很少的url中),并试图对url中的用户输入进行编码。我知道我也可以使用输入验证,但如果我使用ESAPI编码器,它是否有相应的解码器?如果它有,那么它是什么?如果不是,那么可以做什么来执行相同的编码和解码?

  • 问题内容: 我正在编写一些代码来与尚不存在的服务接口,因此我正在编写一个模拟器,以尝试降低当我有机会与实际系统集成时可能遇到的一些问题的风险。该接口基本上是一个REST风格的接口,该接口返回JSON格式的字符串。 接口规范说,将返回JSON格式的响应来代替标准HTTP正文。它还说来自服务器的响应将被zlib压缩,并在标头中设置“ Content- Encoding:gzip”。因此,我创建了一个W

  • 问题内容: 好的,所以我要把握机会,这里的某个人以前使用过zxing。我正在开发Java应用程序,它需要做的一件事是将字节数据数组编码为QR码,然后在以后对其进行解码。 这是我的编码器外观的示例: 此代码中的开始字节数组仅用于对其进行测试。实际的字节数据将有所不同。 这是我的解码器的外观: 是一种将字节数组转换为十六进制字符串的方法。 当我尝试同时运行这两个代码块时,输出如下: 显然,文本已被编码