Spring添加jackson-dataformat-xml后@ResponseBody返回XML,如何同时支持JSON?
这个问题我之前帮不少开发者解决过——当你引入jackson-dataformat-xml依赖后,Spring会自动注册MappingJackson2XmlHttpMessageConverter,而且它的优先级会比默认的JSON转换器更高,所以原本返回JSON的@ResponseBody就自动变成XML了。要同时保留XmlMapper的使用,又维持JSON作为默认返回格式,有几个靠谱的方案:
1. 全局调整消息转换器优先级(推荐全局生效)
创建一个WebMvc配置类,手动指定JSON转换器的优先级高于XML转换器,这样Spring默认会优先选择JSON返回,同时你依然可以通过请求头Accept: application/xml来获取XML格式的响应,也能正常使用XmlMapper处理XML转JSON的逻辑。
import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 先添加JSON转换器,保证优先级更高 converters.add(new MappingJackson2HttpMessageConverter()); // 再添加XML转换器 converters.add(new MappingJackson2XmlHttpMessageConverter()); } }
2. 针对单个接口强制指定返回JSON
如果不想全局修改,只想针对部分接口维持JSON返回,可以在@RequestMapping(或@GetMapping/@PostMapping)中通过produces属性指定返回格式为JSON:
import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController public class YourController { @GetMapping(value = "/your-api", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public YourPojo getYourData() { // 业务逻辑 return new YourPojo(); } }
这样即使全局默认是XML,这个接口也会强制返回JSON,同时你在其他地方依然可以正常使用XmlMapper处理XML转JSON。
3. 手动使用XmlMapper处理XML转JSON逻辑
如果你只是需要在代码里用XmlMapper来做XML到JSON的转换(比如解析XML字符串转成POJO再转JSON),完全不需要担心默认响应格式的问题——直接注入或者实例化XmlMapper就行,不会影响@ResponseBody的默认行为:
import com.fasterxml.jackson.dataformat.xml.XmlMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController public class XmlToJsonController { @Autowired private XmlMapper xmlMapper; // Spring会自动注入这个Bean @PostMapping("/xml-to-json") @ResponseBody public Object convertXmlToJson(@RequestBody String xmlStr) throws Exception { // 先把XML转成POJO YourPojo pojo = xmlMapper.readValue(xmlStr, YourPojo.class); // 这里返回的pojo会自动转成JSON(因为默认消息转换器是JSON) return pojo; } }
补充说明
如果你的Spring Boot版本比较新,也可以通过配置文件快速调整,比如在application.properties中添加:
spring.mvc.converters.preferred-json-mapper=jackson spring.http.converters.preferred-json-mapper=jackson
不过这种方式的兼容性不如手动配置类稳定,还是推荐用第一种配置类的方式。
内容的提问来源于stack exchange,提问作者mmaceachran

