1. 问题概述

在 Spring MVC 开发中,我们经常遇到一个经典踩坑场景:当使用 @PathVariable 映射包含点号(.)的 URI 路径时,变量值会被意外截断。具体表现为,点号之后的内容会被 Spring 误判为文件扩展名(如 .json.xml),导致参数值不完整。

本文将深入分析问题根源,并提供三种解决方案。如果你熟悉 Spring MVC 基础,可直接跳到解决方案部分。

2. 问题根源

Spring 框架的默认行为是导致问题的元凶。Spring 会将路径中最后一个点号之后的内容视为文件扩展名,从而在解析路径变量时自动截断这部分内容。

通过以下示例代码直观感受问题:

@RestController
public class CustomController {
    @GetMapping("/example/{firstValue}/{secondValue}")
    public void example(@PathVariable("firstValue") String firstValue,
      @PathVariable("secondValue") String secondValue) {
        // ...  
    }
}

测试不同 URL 时的参数解析结果:

URL firstValue secondValue
/example/gallery/link gallery link
/example/gallery.df/link.ar gallery.df link
/example/gallery.df/link.com.ar gallery.df link.com

⚠️ 关键发现:

  • 第一个变量不受影响
  • 第二个变量总是被截断(最后一个点号后的内容丢失)

3. 解决方案

方案一:正则表达式映射(推荐)

在路径变量定义中添加正则表达式 .+,强制包含所有点号:

@GetMapping("/example/{firstValue}/{secondValue:.+}")   
public void example(
  @PathVariable("firstValue") String firstValue,
  @PathVariable("secondValue") String secondValue) {
    //...
}

✅ 优点:精准控制,不影响其他接口

方案二:路径尾部添加斜杠

通过在路径变量后添加 / 改变解析逻辑:

@GetMapping("/example/{firstValue}/{secondValue}/")

✅ 优点:实现简单
❌ 缺点:改变 URL 结构,可能影响 RESTful 设计

方案三:全局配置修改

通过自定义配置禁用后缀模式匹配(影响所有接口):

@Configuration
public class CustomWebMvcConfigurationSupport extends WebMvcConfigurationSupport {

    @Override
    protected PathMatchConfigurer getPathMatchConfigurer() {
        PathMatchConfigurer pathMatchConfigurer = super.getPathMatchConfigurer();
        pathMatchConfigurer.setUseSuffixPatternMatch(false);
        return pathMatchConfigurer;
    }
}

⚠️ 注意:

  • 此方案会全局生效
  • 在 Spring 5.3+ 中已默认禁用(见下文说明)

3.1. 重要版本变更说明

⚠️ Spring Framework 5.2.4+ 重要变更

  • setUseSuffixPatternMatch() 方法已标记为废弃
  • 官方不推荐使用路径扩展名进行请求路由和内容协商
  • 原因:难以防御 Reflected File Download (RFD) 攻击

⚠️ Spring Framework 5.3+ 关键调整

  • 后缀模式匹配仅对显式注册的扩展名生效
  • 默认已禁用任意扩展名匹配
  • 结论:在 Spring 5.3+ 中无需手动配置 setUseSuffixPatternMatch(false)

4. 总结

本文系统分析了 Spring MVC 中 @PathVariable 遇到点号被截断的问题,提供了三种解决方案:

  1. 正则表达式映射(推荐):精准控制,无副作用
  2. 路径尾部加斜杠:简单粗暴,但改变 URL 结构
  3. 全局配置:慎用,Spring 5.3+ 已默认优化

完整示例代码可在 GitHub 获取。实际开发中建议优先使用正则方案,既解决问题又保持代码整洁。


原始标题:Spring MVC @PathVariable with a dot (.) gets truncated