控制器怎么返回JSON和XML格式数据_响应格式切换【操作】

4次阅读

spring boot中@restcontroller默认依赖jackson并倾向返回json,但支持xml响应;需引入jackson-dataformat-xml、配置正确注解及避免@enablewebmvc干扰内容协商。

控制器怎么返回JSON和XML格式数据_响应格式切换【操作】

spring boot@RestController 默认只返回 JSON?

不是默认只返回 JSON,而是默认依赖 Jackson,且客户端请求头没明确指定时,它倾向用 application/json 响应。但只要客户端发来 Accept: application/xml,Spring Boot 也能自动转成 XML——前提是项目里有 XML 序列化支持(比如 jackson-dataformat-xmlspring-boot-starter-web 自带的 JAXB 依赖)。

常见错误现象:406 Not Acceptable 错误,或者返回 JSON 却期望 XML;根本原因是类路径下缺 XML 处理器,或实体类没加必要注解。

  • 确保引入了 com.fasterxml.jackson.dataformat:jackson-dataformat-xml(推荐),或保留 JDK 8+ 的 javax.xml.bind:jaxb-api(JDK 11+ 需额外加)
  • 实体类字段必须是 public getter/setter,或加 @JsonProperty(JSON)和 @JacksonXmlProperty(XML)显式控制字段名
  • 避免混用 @XmlRootElement(JAXB)和 Jackson 注解,容易冲突;统一用 Jackson 的 @JacksonXmlRootElement

Content-TypeAccept 头怎么影响响应格式?

Spring Boot 的内容协商(Content Negotiation)靠这两个头驱动:Accept 告诉服务端“我要什么”,Content-Type 是请求体类型(对 GET 无效)。服务端按 Accept 列表顺序匹配可用的 httpMessageConverter

典型场景:postman 测试时忘了设 Accept: application/xml,结果一直拿到 JSON;或者前端 axios 没配 headers: { Accept: 'application/xml' },后端根本收不到切换信号。

  • 浏览器地址栏直接访问接口,默认 Accept: text/html,*/*,Spring 会 fallback 到 JSON(不是 XML)
  • curl -H "Accept: application/xml" 测试最可靠
  • 如果想强制返回 XML,可在方法上加 @RequestMapping(produces = "application/xml"),但会丢掉协商灵活性

为什么加了 @EnableWebMvc 后 XML 不生效?

加了 @EnableWebMvc 就等于放弃 Spring Boot 自动配置的 WebMvcConfigurationSupport,包括默认注册的 Jackson2ObjectMapperBuilderMappingJackson2XmlHttpMessageConverter。此时 XML 转换器不会自动加载,哪怕你引了依赖。

错误表现:所有接口都只返回 JSON,Accept: application/xml 完全被忽略,日志里也看不到 XML converter 初始化记录。

  • 删掉 @EnableWebMvc 是最简单解法(除非你真需要完全自定义 MVC 配置)
  • 如果必须保留,就得手动注册 MappingJackson2XmlHttpMessageConverter,并在 configureMessageConverters 里 add 进去
  • 注意:手动注册时,要确保 MappingJackson2XmlHttpMessageConverterMappingJackson2HttpMessageConverter(JSON)之前,否则协商时 JSON 总是优先匹配

返回 XML 时中文乱码或根节点名不对?

Jackson XML 序列化默认用 UTF-8,但若响应头没带 charset=utf-8,某些老客户端(如 IE、部分 Java HttpClient)可能当 ISO-8859-1 解析;另外,根元素名默认取类名,不加注解就是 <user></user>,而不是你想要的 <user></user><response></response>

  • application.propertiesspring.http.converters.preferred-json-mapper=jackson(不影响 XML),再配 server.servlet.context-path= 等无关项没用,重点是 converter 配置
  • @JacksonXmlRootElement(localName = "user") 控制根节点名
  • 确保 response header 包含 Content-Type: application/xml;charset=UTF-8 —— Spring Boot 2.3+ 默认已带,老版本可加 @Configuration 注册 StringHttpMessageConverter 并设 setDefaultCharset(StandardCharsets.UTF_8)

复杂点在于:同一个实体既要被 JSON 用,又要被 XML 用,注解得兼顾两边;比如 @JsonProperty("user_id")@JacksonXmlProperty(localName = "user-id") 写法不同,稍不注意就漏一个,导致某一种格式字段消失。

text=ZqhQzanResources