diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/config/BfiFeignClientConfig.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/config/BfiFeignClientConfig.java index 535935c7..72396d90 100644 --- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/config/BfiFeignClientConfig.java +++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/config/BfiFeignClientConfig.java @@ -27,14 +27,20 @@ package org.springblade.thirdparty.bfi.config; import feign.Request; import feign.RequestInterceptor; +import feign.codec.Decoder; import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; import org.springblade.thirdparty.bfi.interceptor.BfiRequestInterceptor; import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; /** @@ -71,4 +77,26 @@ public class BfiFeignClientConfig { public Encoder feignFormEncoder(ObjectFactory messageConverters) { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } + + /** + * BFI 专用解码器:金蝶部分接口成功响应缺失 Content-Type 头(kong 网关 chunked 转发丢失, + * 如 cas_paybill/query),默认解码器按 application/octet-stream 匹配不到 JSON 转换器导致 + * "no suitable HttpMessageConverter" 解码失败。缺失 Content-Type 时强制按 JSON 解码, + * 其余响应保持默认解码逻辑(含二进制下载接口) + */ + @Bean + public Decoder bfiDecoder(ObjectFactory messageConverters) { + SpringDecoder defaultDecoder = new SpringDecoder(messageConverters); + MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(); + jacksonConverter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_JSON, MediaType.ALL)); + SpringDecoder forceJsonDecoder = new SpringDecoder(() -> new HttpMessageConverters(jacksonConverter)); + return (response, type) -> { + boolean missingContentType = response.headers().keySet().stream() + .noneMatch("content-type"::equalsIgnoreCase); + if (missingContentType) { + return forceJsonDecoder.decode(response, type); + } + return defaultDecoder.decode(response, type); + }; + } }