Spring MVC 动态支持 JSON/XML 的技巧

引言

在实际开发中,我们经常需要让接口同时支持多种数据格式(如 JSON、XML),以满足不同客户端的请求需求。例如:

  • 前端页面默认使用 JSON 格式;

  • 第三方系统要求返回 XML 格式。

一、Spring MVC 内容协商原理

Spring MVC 的 ContentNegotiation 机制可以根据请求参数或 Accept 头自动选择响应格式。其核心逻辑如下:

  1. 客户端发起请求时,通过 URL 参数Accept 头 声明期望的数据格式。

  2. 服务端根据配置的 MediaType 匹配对应的消息转换器(如 Jackson2HttpMessageConverter)。

  3. 最终返回对应格式的数据。


二、配置内容协商策略

以下是关键配置代码:

复制代码
package com.kjwl.framework.config;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(true)
                // 客户端请求url需要携带一个query参数 默认名称是 format
                .parameterName("format")
                .ignoreAcceptHeader(true) // 忽略Accept头,强制使用默认类型
                // 如果不声明 该query参数 返回的是json  如果你想指定默认返回类型就需要声明
                .defaultContentType(MediaType.APPLICATION_JSON)
                .mediaType("json", MediaType.APPLICATION_JSON)
                .mediaType("xml", MediaType.APPLICATION_XML);

    }
}

三、配置解析
  1. favorParameter(true)

    允许通过 URL 参数(如 ?format=xml)指定返回格式。默认参数名为 format,可通过 parameterName() 自定义。

  2. ignoreAcceptHeader(true)

    是否忽略客户端的 Accept 头。若设置为 true,则强制使用 URL 参数或默认格式;若为 false,则优先使用 Accept 头。

  3. defaultContentType()

    未指定格式时,默认返回 JSON。

  4. mediaType()

    注册支持的格式映射。例如,format=xml 对应 APPLICATION_XML


四、实现 XML 支持

仅仅配置内容协商还不够! 需添加 XML 消息转换器依赖:

复制代码
<!-- Maven 依赖:Jackson XML 处理 -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Spring Boot 会自动检测该依赖,并注册 MappingJackson2XmlHttpMessageConverter


五、接口使用示例
复制代码
@RestController
public class UserController {
    
    @GetMapping("/user")
    public User getUser() {
        return new User("tom", "tom@example.com");
    }
}

测试请求:

  1. 默认返回 JSON

    GET /user

    响应:{"name": "tom", "email": "tom@example.com"}

  2. 通过参数返回 XML

    GET /user?format=xml

    响应:

    <User>

    <name>tom</name>

    <email>tom@example.com</email>

    </User>

相关推荐
敲敲千反田5 小时前
Spring 相关
java·后端·spring
树下水月7 小时前
Easyswoole 框架session在高并发/频繁请求下数据丢失问题记录
java·后端·spring
贫民窟的勇敢爷们8 小时前
Spring Security OAuth2.0 技术详解:分布式系统安全认证的标准方案
java·安全·spring
_Evan_Yao9 小时前
return 的迷途:try-catch-finally 中 return 的诡异顺序与 Spring 事务暗坑
java·后端·spring·mybatis
一只大袋鼠10 小时前
Spring 事务管理三种实现方式
java·数据库·spring·声明式事务
nj012820 小时前
Spring 循环依赖详解:三级缓存、早期引用、AOP 代理与懒加载
java·spring·缓存
Maiko Star1 天前
让 AI 开口说话:Spring AI Alibaba 语音合成(TTS)实战
java·人工智能·spring·springai
KNeeg_1 天前
黑马点评完整代码(RabbitMQ优化)+简历编写+面试重点 ⭐
java·redis·后端·spring·面试·职场和发展·黑马点评
铁皮哥1 天前
【后端/Agent 开发】给你的项目配置一套 .claude/ 工作流:别再裸用 Claude Code 了!
java·windows·python·spring·github·maven·生活