场景描述
在使用open feign调用某服务时,接口操作报出如下异常
2022-03-07 17:53:18.453 [http-nio-9999-exec-1] ERROR [org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]175] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.codec.DecodeException: Could not extract response: no suitable HttpMessageConverter found for response type [class cn.monyun.api.response.MonYunResponse] and content type [text/json;charset=utf-8]] with root cause [TID: N/A]
org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class cn.monyun.api.response.MonYunResponse] and content type [text/json;charset=utf-8]
乍一看,有点懵,按照官方文档显示返回值为json,但是jackson转换失败,仔细查看接口返回content-type为text/json;charset=utf-8
,想了半天没见过这种类型,经过一顿查找,最后发现这个类型竟然是山寨版。。官方版本应为 application/json
,但是没办法,对方系统已经在线上运行了,只能添加解析器,支持一下这种类型转换
处理步骤
新增消息转换器,需要兼容支持text/json
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
* @author chunyang.leng
* @date 2022-03-07 7:17 PM
*/
@Configuration
public class TextMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
private static final Logger logger = LoggerFactory.getLogger(TextMappingJackson2HttpMessageConverter.class);
public TextMappingJackson2HttpMessageConverter() {
// 先将原先支持的MediaType列表拷出
List<MediaType> mediaTypeList = new ArrayList<>(this.getSupportedMediaTypes());
//加入对text/plain的支持
mediaTypeList.add(new MediaType("text", "json", StandardCharsets.UTF_8));
//将已经加入了text/json的MediaType支持列表设置为其支持的媒体类型列表
this.setSupportedMediaTypes(mediaTypeList);
logger.info("==================> 启用 text/json系列消息转换器");
}
}
增加 open feign 解码器
import feign.codec.Decoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
private HttpMessageConverters messageConverters = null;
/**
* 补充 http 协议消息转换器
* content-type:text/json
*
* @param converter 自定义的消息转换器
* @return openFeign 解码器
*/
@Bean
@ConditionalOnBean(TextMappingJackson2HttpMessageConverter.class)
public Decoder feignDecoder(TextMappingJackson2HttpMessageConverter converter){
if (messageConverters == null){
messageConverters = new HttpMessageConverters(converter);
}
ObjectFactory<HttpMessageConverters> objectFactory = () -> messageConverters;
logger.info("==================> 初始化openFeign text/json支持解析器");
return new SpringDecoder(objectFactory);
}
经过测试,已经可以正常转换
附录
标准的MIME类型链接 :
《百度百科》https://baike.baidu.com/item/MIME/2900607?fr=aladdin
《HTML4.01 规范》 https://www.w3.org/TR/html4/types.html#h-6.7