Spring Boot 2.7.7 WebClient调用SOAP接口遇缓冲字节超限异常
解决WebClient调用SOAP服务时的DataBufferLimitException异常
问题根源
异常提示的Exceeded limit on max bytes to buffer : 262144说明当前使用的解码器内存缓冲上限还是默认的256KB,你配置的16MB/512MB没有正确应用到自定义的Jaxb2SoapDecoder上。
具体修复步骤
1. 修正自定义解码器的内存缓冲配置
你的Jaxb2SoapDecoder重写了setMaxInMemorySize方法,但如果Spring初始化时没有调用该方法,解码器仍会使用默认的256KB上限。在解码器构造阶段主动设置缓冲大小:
class Jaxb2SoapDecoder : Jaxb2XmlDecoder() { // 在初始化时直接设置缓冲大小,无需依赖外部调用 init { super.setMaxInMemorySize(16 * 1024 * 1024) } override fun setMaxInMemorySize(byteCount: Int) { // 强制保持固定缓冲大小,避免被外部修改 super.setMaxInMemorySize(16 * 1024 * 1024) } @Throws(DecodingException::class) override fun decode(dataBuffer: DataBuffer, targetType: ResolvableType, @Nullable mimeType: MimeType?, @Nullable hints: MutableMap<String, Any>?): Any { // 原有解码逻辑 ..... } }
2. 简化WebClient的ExchangeStrategies配置
移除WebClient构建器中重复的codecs配置,避免与自定义exchangeStrategies冲突:
@Bean fun webClientXml(): WebClient { val httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100000) .doOnConnected { it.addHandlerLast(ReadTimeoutHandler(100)) it.addHandlerLast(WriteTimeoutHandler(100)) } .resolver(DefaultAddressResolverGroup.INSTANCE) val exchangeStrategies = ExchangeStrategies.builder().codecs { config -> // 配置默认codec的缓冲大小(如果使用到默认解码器) config.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) // 注册自定义编解码器 config.customCodecs().register(Jaxb2SoapEncoder()) config.customCodecs().register(Jaxb2SoapDecoder()) }.build() return WebClient.builder() .clientConnector(ReactorClientHttpConnector(httpClient)) .exchangeStrategies(exchangeStrategies) .build() }
3. 验证全局配置有效性(可选)
如果你希望通过application.yml的全局配置生效,需要基于全局Codec配置构建ExchangeStrategies,而不是手动创建全新的实例:
@Bean fun webClientXml(codecConfigurer: CodecConfigurer): WebClient { val httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100000) .doOnConnected { it.addHandlerLast(ReadTimeoutHandler(100)) it.addHandlerLast(WriteTimeoutHandler(100)) } .resolver(DefaultAddressResolverGroup.INSTANCE) // 使用全局配置的CodecConfigurer,再添加自定义编解码器 val exchangeStrategies = ExchangeStrategies.builder(codecConfigurer).codecs { config -> config.customCodecs().register(Jaxb2SoapEncoder()) config.customCodecs().register(Jaxb2SoapDecoder()) }.build() return WebClient.builder() .clientConnector(ReactorClientHttpConnector(httpClient)) .exchangeStrategies(exchangeStrategies) .build() }
此时application.yml中的spring.codec.max-in-memory-size: 512MB会生效,同时自定义解码器可调整为读取全局配置(或保持硬编码,根据需求选择)。
关键说明
- 自定义编解码器不会自动继承全局
codec配置,必须显式设置缓冲大小或基于全局配置构建ExchangeStrategies。 - WebClient构建器中
exchangeStrategies的优先级高于单独的codecs配置,避免重复配置导致冲突。
内容的提问来源于stack exchange,提问作者Aymen Kanzari
相关产品推荐
相关产品推荐

