最近在使用
springboot
调用第三方接口的时候,出现了这个异常
Could not extract response: no suitable HttpMessageConverter found for response type [cn.justme.sboot.entity.BaseResp<java.lang.String>] and content type [text/plain;charset=UTF-8],
这里就来分析一下具体问题
事件还原
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
feign调用
@FeignClient(name = "test", url = "http://localhost:8080")
public interface TestClient {
@GetMapping("/api/test")
BaseResp<String> test();
}
三方接口返回的是json,这里我是使用feign调用。
第三方接口
接口: /api/test
{
"status": 0,
"message": "",
"data": null
}
我们可以看到
Content-Type: text/plain;charset=UTF-8
,
原因分析
springboot默认的处理json的 HttpMessageConverter
为 MappingJackson2HttpMessageConverter
。
public MappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"));
}
但是 MappingJackson2HttpMessageConverter
只支持 APPLICATION_JSON
类型,所以springboot没有找到合适的 HttpMessageConverter
,于是报出了上面的异常。
feign默认的Decoder为 SpringDecoder
public class SpringDecoder implements Decoder {
private ObjectFactory<HttpMessageConverters> messageConverters;
public SpringDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
this.messageConverters = messageConverters;
}
}
我们看一下默认的 messageConverters
解决方案
解决该问题,只要添加
MediaType.TEXT_PLAIN
类型的支持即可
方案一
仅仅在该 FeignClient
做 MediaType.TEXT_PLAIN
的支持,不影响其他的client。
@FeignClient(name = "test", url = "http://localhost:8080", configuration = TestClient.FeignTestConfiguration.class)
public interface TestClient {
@GetMapping(“/api/test”)
BaseResp test();
class FeignTestConfiguration {
@Bean
public Decoder textPlainDecoder() {
return new SpringDecoder(() -> new HttpMessageConverters(new CustomMappingJackson2HttpMessageConverter()));
}
}
class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
@Override
public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) {
super.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
}
}
}
调用接口,查看该FeignClient
的Decoder
此时调用成功。
方案二
全局修改,使所有的调用都支持TEXT_PLAIN
的Content-Type
@Configuration
public class TestConfig {
@Bean
public MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() {
return new CustomMappingJackson2HttpMessageConverter();
}
static class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
public CustomMappingJackson2HttpMessageConverter() {
setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
}
}
}
方案三
我们也可以实现 WebMvcConfigurer
下面接口来实现对应功能。
/**
* Configure the {@link HttpMessageConverter}s to use for reading or writing
* to the body of the request or response. If no converters are added, a
* default list of converters is registered.
* <p><strong>Note</strong> that adding converters to the list, turns off
* default converter registration. To simply add a converter without impacting
* default registration, consider using the method
* {@link #extendMessageConverters(java.util.List)} instead.
* @param converters initially an empty list of converters
*/
default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
/**
* A hook for extending or modifying the list of converters after it has been
* configured. This may be useful for example to allow default converters to
* be registered and then insert a custom converter through this method.
* @param converters the list of configured converters to extend.
* @since 4.1.3
*/
default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
原文:springboot: no suitable HttpMessageConverter found for response | SHIV STEP
作者:justsme