You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用返回纯文本String的第三方服务时FeignClient报错如何解决?

问题原因

报错本质是Feign默认使用JSON解码器解析响应,但第三方服务返回的是纯文本OK(无引号,不属于合法JSON格式),导致解码器无法识别,抛出解析异常。

解决方案

以下几种方案可按需选择:

方案1:为目标FeignClient单独配置文本解码器

针对该第三方服务单独配置解码器,确保Feign用字符串转换器处理响应:

  1. 创建Feign配置类:
@Configuration
public class ThirdPartyFeignConfig {
    @Bean
    public Decoder feignDecoder() {
        // 用StringHttpMessageConverter处理text/plain类型响应
        SpringDecoder decoder = new SpringDecoder(() -> 
            new HttpMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8))
        );
        return decoder;
    }
}
  1. 在FeignClient上指定该配置:
@FeignClient(
    name = "third-party-service", 
    url = "${third-party.service.url}",
    configuration = ThirdPartyFeignConfig.class
)
public interface ThirdPartyFeignClient {
    @PostMapping(
        path = "/url", 
        consumes = MediaType.APPLICATION_JSON_VALUE,
        produces = MediaType.TEXT_PLAIN_VALUE
    )
    String apiService(@RequestBody myDTO application) throws Exception;
}

方案2:全局配置兼容文本响应(谨慎使用)

如果项目中多个Feign接口需要处理纯文本响应,可全局扩展解码器:

@Configuration
public class GlobalFeignConfig {
    @Bean
    public Decoder feignDecoder(ObjectProvider<HttpMessageConverters> messageConverters) {
        // 扩展默认解码器,添加字符串转换器
        HttpMessageConverters converters = messageConverters.getIfAvailable();
        List<HttpMessageConverter<?>> converterList = new ArrayList<>(converters.getConverters());
        converterList.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return new SpringDecoder(() -> new HttpMessageConverters(converterList));
    }
}

注意:全局配置会影响所有FeignClient,需确保不会干扰其他JSON格式接口的解析逻辑。

方案3:自定义解码器精准匹配目标接口

如果需要仅处理/url接口的文本响应,可实现细粒度控制的解码器:

  1. 自定义Decoder实现:
public class TextAwareDecoder implements Decoder {
    private final Decoder defaultJsonDecoder;
    private final StringDecoder stringDecoder;

    public TextAwareDecoder(Decoder defaultJsonDecoder) {
        this.defaultJsonDecoder = defaultJsonDecoder;
        this.stringDecoder = new StringDecoder();
    }

    @Override
    public Object decode(Response response, Type type) throws IOException, FeignException {
        // 判断是否为目标接口或文本类型响应
        boolean isTargetUrl = "/url".equals(response.request().url().substring(response.request().url().lastIndexOf("/")));
        boolean isTextResponse = response.headers()
                .getOrDefault("Content-Type", Collections.emptyList())
                .stream()
                .anyMatch(ct -> ct.contains(MediaType.TEXT_PLAIN_VALUE));

        if (isTargetUrl || isTextResponse) {
            return stringDecoder.decode(response, type);
        }
        return defaultJsonDecoder.decode(response, type);
    }
}
  1. 配置该解码器:
@Configuration
public class ThirdPartyFeignConfig {
    @Bean
    public Decoder feignDecoder(ObjectProvider<HttpMessageConverters> messageConverters) {
        SpringDecoder defaultDecoder = new SpringDecoder(messageConverters);
        return new TextAwareDecoder(defaultDecoder);
    }
}

额外注意点

  • 若第三方服务返回的Content-Type是application/json但内容为无引号的OK,必须强制使用字符串解码器处理,否则JSON解码器仍会报错。
  • 保持Feign接口的produces属性为MediaType.TEXT_PLAIN_VALUE,明确告知Feign预期的响应类型。

内容的提问来源于stack exchange,提问作者cucuru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:55:33