You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring RestController如何实现URL后缀驱动的XML/JSON响应切换

解决Spring RestController基于URL后缀的内容协商问题

问题分析

你遇到的404错误核心原因是:Spring MVC默认会将URL中的后缀(如.json)视为请求映射的一部分,而非内容协商的标识。当访问/employees.json时,Spring会寻找映射路径为/employees.json的Controller方法,但你的Controller只有/employees的映射,因此返回404。之前的WebMvcConfigurer配置仅设置了内容协商规则,但未配置路径匹配策略,导致后缀无法被正确解析为媒体类型;拦截器方案无效则是因为请求未匹配到Controller就已返回404,拦截器根本不会执行。

解决方案

要复现JAX-RS的URL后缀内容协商功能,需完成以下三步:

1. 添加XML序列化依赖

Spring默认自带JSON序列化支持,但XML需要额外引入Jackson XML依赖(Maven示例):

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

2. 配置WebMvcConfigurer

调整配置,同时设置内容协商规则和路径匹配策略,让Spring将URL后缀解析为媒体类型而非映射路径的一部分:

package com.example.spring_rest_to_graphql;

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.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.util.pattern.PathPatternParser;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true)
                  .favorParameter(false)
                  .ignoreAcceptHeader(true)
                  .useRegisteredExtensionsOnly(true)
                  .defaultContentType(MediaType.APPLICATION_XML) // 与原JAX-RS默认返回XML一致
                  .mediaType("json", MediaType.APPLICATION_JSON)
                  .mediaType("xml", MediaType.APPLICATION_XML);
    }

    @Override
    public void configurePathMatching(PathMatchConfigurer configurer) {
        // Spring Boot 2.6+ 默认使用PathPatternParser,开启注册后缀匹配
        PathPatternParser parser = new PathPatternParser();
        parser.setUseRegisteredSuffixPatternMatch(true);
        configurer.setPatternParser(parser);

        // 若使用Spring Boot 2.6之前版本(默认AntPathMatcher),替换为以下代码:
        // configurer.setUseSuffixPatternMatch(true)
        //           .setUseRegisteredSuffixPatternMatch(true);
    }
}

3. 编写RestController与实体类

确保实体类支持XML序列化,Controller映射路径与原JAX-RS一致:

实体类示例

package com.example.spring_rest_to_graphql;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "employee")
public class Employee {
    private int id;
    private String name;

    // 必须提供无参构造函数,用于序列化/反序列化
    public Employee() {}

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter和Setter方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

Controller示例

package com.example.spring_rest_to_graphql;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    @GetMapping
    public List<Employee> getEmployees() {
        return Arrays.asList(
                new Employee(1, "Alice"),
                new Employee(2, "Bob")
        );
    }
}

验证结果

  • 访问http://localhost:8080/employees:默认返回XML格式
  • 访问http://localhost:8080/employees.json:返回JSON格式
  • 访问http://localhost:8080/employees.xml:返回XML格式

内容的提问来源于stack exchange,提问作者sravan ganji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:00:54