添加jackson-dataformat-xml后Spring Boot 2.5.6启动失败求助
你在Spring Boot 2.5.6中添加jackson-dataformat-xml依赖后,启动时coocoo Bean初始化失败,核心原因是:
- 外部依赖的代码通过
new RestTemplate().exchange(...)发起请求,未显式设置Accept头,RestTemplate自动生成的Accept包含XML相关类型 - 尽管响应实际是JSON(Content-Type为
application/json;charset=UTF-8),但系统错误地尝试用XML解析器处理,导致JSON格式解析异常(期望XML的<开头,实际是JSON的{)
你尝试的ClientHttpRequestInterceptor无效是因为拦截器需要注入到Spring管理的RestTemplate实例中,而外部代码是直接new的实例;spring.xml.ignore=true也无法解决RestTemplate自动生成Accept头的问题。
方案1:用AOP强制修改Accept请求头
通过AOP拦截所有RestTemplate的exchange方法调用,强制设置Accept头为仅接受JSON,从请求源头避免XML解析触发。
- 先添加AOP依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 编写切面类:
@Aspect @Component public class RestTemplateAcceptModifier { @Around("execution(* org.springframework.web.client.RestTemplate.exchange(..))") public Object adjustAcceptHeader(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); // 遍历参数,找到HttpEntity对象修改请求头 for (int i = 0; i < args.length; i++) { if (args[i] instanceof HttpEntity) { HttpEntity<?> original = (HttpEntity<?>) args[i]; HttpHeaders newHeaders = new HttpHeaders(); newHeaders.putAll(original.getHeaders()); // 强制设置Accept为仅JSON newHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); args[i] = new HttpEntity<>(original.getBody(), newHeaders); break; } } return joinPoint.proceed(args); } }
这个切面会拦截所有RestTemplate的exchange调用,不管实例是Spring管理还是new出来的,都能修改请求头。
方案2:调整消息转换器优先级
让JSON转换器的优先级高于XML转换器,即使Accept头包含XML类型,系统也会优先用JSON转换器处理application/json类型的响应。
编写配置类注册高优先级的JSON转换器:
@Configuration public class HttpMessageConverterConfig { @Bean public MappingJackson2HttpMessageConverter prioritizedJsonConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); // 设置优先级为最高(数值越小优先级越高) converter.setOrder(0); return converter; } }
原理:RestTemplate初始化时会加载所有可用的HttpMessageConverter,将JSON转换器设为最高优先级后,遇到application/json类型的响应会优先选择JSON解析,避免XML解析器错误介入。
方案3:排除XML转换器的自动配置
如果你的应用不需要XML解析功能,可以直接禁用Spring Boot对MappingJackson2XmlHttpMessageConverter的自动配置,从根本上移除XML解析能力。
方式1:启动类注解排除
@SpringBootApplication(exclude = {JacksonAutoConfiguration.JacksonXmlAutoConfiguration.class}) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
方式2:配置文件排除
在application.properties中添加:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonXmlAutoConfiguration
这样RestTemplate的转换器列表中不会包含XML转换器,自然只会用JSON解析响应。
内容的提问来源于stack exchange,提问作者colddog

