Fre*_*edo 5 spring-boot spring-webflux
我收到了DataBufferLimitException对 HTTP 请求的响应。我在用spring-boot-starter-parent:2.5.0,spring-cloud.version:2020.0.2。我几乎已经尝试了此处描述的所有选项(DataBufferLimitException: Exceeded limit on max bytes to buffer webflux error)和此处(configure spring.codec.max-in-memory-size When using ReactiveElasticsearchClient),但没有成功。还有什么我可以尝试的吗?这是我创建网络客户端的代码:
private WebClient buildWebClient(long custId) {
return WebClient.builder()
.clientConnector(createWebClientWithTimeout())
// Add base url to all requests (callers only need to add the path and query params)
.baseUrl(baseUrl)
// Filter to add bearer token to auth header before sending request
.filter((request, next) -> getToken(custId).map(setAuthHeader(request)).flatMap(next::exchange))
// Filter to send the request, and try again if it has an auth error
.filter((request, next) -> next.exchange(request).flatMap(clientResponse -> {
if (clientResponse.statusCode() == HttpStatus.UNAUTHORIZED) {
logger.error("Received 401 Unauthorized from linkedin for request: {} {} with X-LI-UUID header: {}", request.method(), request.url(),
clientResponse.headers().header(LINKEDIN_HEADER));
// Retry once if auth failed
return clientResponse.bodyToMono(String.class)
.doOnNext(err -> logger.warn("Received 401 from linkedin; retrying once. Error body: {}", err))
.then(refreshToken(custId).map(setAuthHeader(request)).flatMap(next::exchange));
} else if (clientResponse.statusCode().isError()) {
logger.error("Received error status code: {} from linkedin for request: {} {} with X-LI-UUID header: {}", clientResponse.statusCode(), request.method(),
request.url(), clientResponse.headers().header(LINKEDIN_HEADER));
} else {
logger.debug("Received status code: {} from linkedin for request: {} {}", clientResponse.statusCode(), request.method(), request.url());
}
// If not a 401, just return the response
return Mono.just(clientResponse);
})).build();
}
Run Code Online (Sandbox Code Playgroud)
将spring.codec.max-in-memory-size=16MB添加到属性不起作用,使用ExchangeStrategies显式设置值不起作用,实现WebFluxConfigurer不起作用。这段代码在 spring-boot-starter-parent:2.1.6.RELEASE 下运行良好。关于我下一步可以尝试什么有什么建议吗?
Spring Boot 为您预先配置了 WebClienter.Builder,这使得 spring.codec.max-in-memory-size 这样的设置毕竟可以工作。
要使用这个预配置的 WebClient.Builder,您需要将其注入到您的服务中,这与您在上面的示例中所做的不同。您似乎直接使用 WebClient.builder() 方法。
此代码与应用程序属性spring.codec.max-in-memory-size一起可以工作:
@Service
public class Foo(WebClient.Builder injectedPreConfiguredBuilder) {
private WebClient buildWebClient(long custId) {
return injectedPreConfiguredBuilder
.clientConnector(createWebClientWithTimeout())
// Add base url to all requests (callers only need to add the path and query params)
.baseUrl(baseUrl)
// Filter to add bearer token to auth header before sending request
.filter((request, next) -> getToken(custId).map(setAuthHeader(request)).flatMap(next::exchange))
// Filter to send the request, and try again if it has an auth error
.filter((request, next) -> next.exchange(request).flatMap(clientResponse -> {
if (clientResponse.statusCode() == HttpStatus.UNAUTHORIZED) {
logger.error("Received 401 Unauthorized from linkedin for request: {} {} with X-LI-UUID header: {}", request.method(), request.url(),
clientResponse.headers().header(LINKEDIN_HEADER));
// Retry once if auth failed
return clientResponse.bodyToMono(String.class)
.doOnNext(err -> logger.warn("Received 401 from linkedin; retrying once. Error body: {}", err))
.then(refreshToken(custId).map(setAuthHeader(request)).flatMap(next::exchange));
} else if (clientResponse.statusCode().isError()) {
logger.error("Received error status code: {} from linkedin for request: {} {} with X-LI-UUID header: {}", clientResponse.statusCode(), request.method(),
request.url(), clientResponse.headers().header(LINKEDIN_HEADER));
} else {
logger.debug("Received status code: {} from linkedin for request: {} {}", clientResponse.statusCode(), request.method(), request.url());
}
// If not a 401, just return the response
return Mono.just(clientResponse);
})).build();
}
}
Run Code Online (Sandbox Code Playgroud)
另外,您需要记住,您需要在测试中使用注入/自动装配的 WebClient.Builder 才能使该属性正常工作!
如果您想推出自己的 WebClient.Builder,可以通过编程方式设置缓冲区大小。
科特林示例:
val webClient = WebClient.builder()
.exchangeStrategies(
ExchangeStrategies.builder().codecs {
it.defaultCodecs().maxInMemorySize(1000000) // in bytes
}.build()
).build()
Run Code Online (Sandbox Code Playgroud)
Java 示例:
WebClient.builder()
.exchangeStrategies(ExchangeStrategies.builder().codecs(
clientCodecConfigurer ->
clientCodecConfigurer.defaultCodecs().maxInMemorySize(1000000))
.build())
.baseUrl("https://stackoverflow.com/posts/68986553/")
.build();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15248 次 |
| 最近记录: |