【问题标题】:Java webclient client response memory issueJava webclient客户端响应内存问题
【发布时间】:2021-07-10 11:05:42
【问题描述】:

有一个数据库,它有 2 个唯一键。托管了一个 API 来查看数据库的值,比如说书籍数据库,它有一个书籍 ID 和另一个唯一 ID。 API 采用唯一 id 并以 JSON 格式返回图书的完整信息。这个信息非常大。我想创建一个映射器程序,它可以在这个 API 的帮助下将唯一的 id 转换为书的 id。 我正在使用

创建一个网络客户端
webClient = WebClient.builder().baseUrl(host).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader("Authorization", apiAuth).defaultHeader("Accept-Encoding", "gzip, deflate")
                .build();

所需的书籍详细信息将包含在主机 uri 中,例如https://example.com/book?uniqueCode=I03909&size=1 和多条记录可以通过用逗号给出多个uniqueCodes并给出大小值来实现。

我正在通过以下方式提出获取请求:

    String response = webClient.get().uri(
            uriBuilder -> uriBuilder.path("/books/")
                    .queryParam("ucodes", ucodes)
                    .queryParam("size", ucodesList.size())
                    .build())
            .retrieve().bodyToMono(String.class).block();

我从这里给出逗号分隔的 ucode 和大小。然后我得到一个包含书籍列表的 json 字符串,每本书都有很多字段,包括书籍 ID、作者、出版年份等。但问题是我只想要书的 id 数据,但是有很多数据来了,所以缓冲区快满了,异常来了。有什么方法可以过滤并仅获取所需的数据并防止此缓冲区满异常。

回复是这样的:

{
"books":[
{
"ucode":"reer2121"
"bookId":"22"
"author":.........
......
......
......

}
]
}

这是一个例外:

org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
    at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:101)
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Body from GET http....

【问题讨论】:

标签: java json spring spring-boot webclient


【解决方案1】:

我不知道如果 API 以这种方式建模,是否有过滤您需要的方法。

你可以增加DataBufferLimit

webClient = WebClient.builder().baseUrl(host).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .exchangeStrategies(ExchangeStrategies.builder()
                        .codecs(configurer -> configurer
                                .defaultCodecs()
                                .maxInMemorySize(10 * 1024 * 1024)) // 10 MB
                        .build())
                .defaultHeader("Authorization", apiAuth).defaultHeader("Accept-Encoding", "gzip, deflate")
                .build();

增加到处理 10 MB,如果需要,您可以添加更多。

【讨论】:

    猜你喜欢
    • 2022-12-15
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多