Feign返回text/plain导致DecodeException问题与解决方案总结

Feign返回text/plain导致DecodeException问题与解决方案

1. 问题现象

在 Spring Cloud 项目集成 Feign 时,调用第三方/后端接口返回如下报错:

feign.codec.DecodeException: Could not extract response: no suitable HttpMessageConverter found for response type [class ...WechatMiniCode2SessionResponse] and content type [text/plain]

原因分析

  • 后端接口返回的 Content-Typetext/plain
  • Feign 客户端(Spring Cloud OpenFeign)本地需要将响应反序列化为 Java 对象,但 Spring 自动配置的 HttpMessageConverter 没有对应类型的转换器
  • 导致 Feign 在反序列化时找不到合适的 Converter,抛出 DecodeException

2. 解决思路

2.1 建议优先方案:让接口返回 application/json

  • 如果你能够修改服务端接口代码,建议将响应内容的 Content-Type 设置为 application/json,这样 Feign 可以自动序列化为 Java 对象

示例代码(Spring MVC Controller):

@ResponseBody
@RequestMapping(
  value = "/api/xxx",
  produces = MediaType.APPLICATION_JSON_VALUE
)
public WechatMiniCode2SessionResponse someHandler(...) {
    ...
}

2.2 不能修改后端时的解决方案

Feign局部配置,让Jackson支持 text/plain

自定义 Feign 的 Decoder,让 MappingJackson2HttpMessageConverter 支持 text/plain

import com.fasterxml.jackson.databind.ObjectMapper;
import feign.codec.Decoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.Arrays;
import java.util.List;

@Configuration
public class FeignConfig {
    @Bean
    public Decoder feignDecoder() {
        // 添加对text/plain的支持
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(
            Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)
        );
        List<HttpMessageConverter<?>> converters = Arrays.asList(converter);
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(converters);
        return new SpringDecoder(objectFactory);
    }
}

然后在 FeignClient 接口上配置:

@FeignClient(name = "your-service", configuration = FeignConfig.class)
public interface YourFeignClient {
    @PostMapping("/api/xxx")
    WechatMiniCode2SessionResponse code2session(...);
}
posted @ 2025-07-28 11:36  王清脆  阅读(209)  评论(0)    收藏  举报