Spring Boot 1.5添加XML消息转换器导致Consul健康检查406错误
问题原因分析
你遇到的问题核心在于自定义消息转换器替换了Spring Boot默认的消息转换器集合,而Consul健康检查请求的Accept头是text/plain,你的自定义转换器里没有能处理这个媒体类型的实现,所以就抛出了HttpMediaTypeNotAcceptableException。
具体来说:
- 当你手动注册
MarshallingHttpMessageConverter和MappingJackson2HttpMessageConverter这两个Bean时,Spring Boot会用这两个转换器完全替换掉默认的转换器列表。 - 默认情况下,Spring Boot会包含
StringHttpMessageConverter,它专门处理text/plain这类媒体类型,能把响应转换成纯文本格式返回给Consul。 - 你用curl发送
accept=application/json的请求能正常工作,是因为你的JSON转换器明确支持这个类型,但Consul的请求是text/plain,没有对应的转换器能处理,所以报错。
解决方案
下面提供几种可行的解决办法,你可以根据自己的需求选择:
1. 给现有转换器添加text/plain支持
直接在XML和JSON转换器的支持媒体类型里加上text/plain,这样它们就能处理Consul的请求,返回对应格式的响应:
修改XML转换器代码:
@Bean public MarshallingHttpMessageConverter marshallingHttpMessageConverter() { Jaxb2Marshaller jaxb2Marshaller = jaxb2Marshaller(); MarshallingHttpMessageConverter marshallingHttpMessageConverter = new MarshallingHttpMessageConverter(); marshallingHttpMessageConverter.setMarshaller(jaxb2Marshaller); marshallingHttpMessageConverter.setUnmarshaller(jaxb2Marshaller); List<MediaType> supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_XML); supportedMediaTypes.add(MediaType.TEXT_PLAIN); // 新增支持text/plain marshallingHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes); return marshallingHttpMessageConverter; }
修改JSON转换器代码:
@Bean public MappingJackson2HttpMessageConverter marshallingHttpMessageConverterJson() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(new ObjectMapper()); List<MediaType> supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.TEXT_PLAIN); // 新增支持text/plain converter.setSupportedMediaTypes(supportedMediaTypes); return converter; }
2. 保留默认转换器,追加自定义转换器
不要直接注册转换器Bean,而是通过WebMvcConfigurer来追加自定义转换器,这样默认的转换器(比如处理text/plain的StringHttpMessageConverter)会被保留:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 配置XML转换器并追加到列表 Jaxb2Marshaller jaxbMarshaller = new Jaxb2Marshaller(); // 这里可以配置jaxbMarshaller的扫描包等属性,比如jaxbMarshaller.setPackagesToScan("com.yourpackage"); MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(jaxbMarshaller, jaxbMarshaller); xmlConverter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_XML)); converters.add(xmlConverter); // 配置JSON转换器并追加到列表 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); jsonConverter.setObjectMapper(new ObjectMapper()); jsonConverter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_JSON)); converters.add(jsonConverter); // 注意:不要调用converters.clear(),否则会清空默认转换器 } }
3. 单独添加处理text/plain的转换器
如果不想修改现有转换器的支持类型,可以单独注册一个StringHttpMessageConverter来处理text/plain请求:
@Bean public StringHttpMessageConverter stringHttpMessageConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter(); converter.setSupportedMediaTypes(List.of(MediaType.TEXT_PLAIN)); return converter; }
总结
本质问题是自定义转换器覆盖了默认集合,导致缺失text/plain的处理能力。只要让你的转换器列表里存在能处理该类型的实现,Consul的健康检查就能正常工作了。
内容的提问来源于stack exchange,提问作者Bizon4ik
相关产品推荐
相关产品推荐

