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

@PathVariable接收fileName时合法扩展名请求返回406 Not Acceptable问题

问题分析

这个问题典型得很,一看就是Web框架的**内容协商(Content Negotiation)**机制在搞事情——406 Not Acceptable本身就是说服务器没法生成符合客户端Accept头要求的响应,而这里刚好是「合法扩展名触发406,非法扩展名正常返回JSON」,根源大概率是框架自动把常见扩展名和特定媒体类型绑定了,和你要返回的JSON格式冲突了:

  • 对于item-1.exx、item-1.855这类「非标准扩展名」,框架找不到对应的默认媒体类型,就会 fallback 到你处理器默认的响应类型(比如application/json),所以能正常返回包含文件名的JSON。
  • 对于.png、.jpg、.exe这类标准扩展名,框架会自动关联对应的媒体类型(比如.png对应image/png,.exe对应application/octet-stream),如果你的处理器没有明确指定返回JSON,或者客户端的Accept头不包含这些媒体类型,就会触发406错误。

排查与解决方案

1. 先确认请求的Accept头

用curl或Postman发起请求时,检查请求头里的Accept字段:

  • 如果客户端发送的是Accept: application/json,但框架认为.png应该返回image/png,两者不匹配就会返回406。
  • 示例curl命令:
    curl -v http://your-domain/test/item-1.png -H "Accept: application/json"
    

2. 禁用框架的「扩展名驱动内容协商」

很多Web框架(比如Spring Boot、ASP.NET)默认会根据URL后缀自动推断响应媒体类型,你可以直接禁用这个功能:

  • Spring Boot:在application.properties里添加配置:
    spring.mvc.contentnegotiation.favor-path-extension=false
    # 或者更彻底一点,关闭后缀匹配
    spring.mvc.pathmatch.matching-strategy=PATH_PATTERN_PARSER
    
  • JAX-RS(Jersey):移除MediaTypeMappingFeature相关配置,或者在资源方法上明确覆盖媒体类型。

3. 强制指定处理器方法的响应类型

在你的处理器方法上,明确声明返回application/json,不管URL后缀是什么:

  • Spring MVC示例:
    @GetMapping(value = "/test/{fileName}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Map<String, String>> getFileName(@PathVariable String fileName) {
        Map<String, String> response = new HashMap<>();
        response.put("fileName", fileName);
        return ResponseEntity.ok(response);
    }
    
  • 这样配置后,服务器会强制返回JSON格式,只要客户端的Accept头包含application/json(或者客户端不指定Accept头),就不会再返回406。

4. 自定义媒体类型映射(如果需要保留扩展名功能)

如果你既要保留扩展名和媒体类型的关联,又要让这些路径能返回JSON,可以添加自定义映射:

  • Spring Boot示例:在配置类里添加:
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer
                .favorPathExtension(true)
                .mediaType("png", MediaType.APPLICATION_JSON_VALUE)
                .mediaType("jpg", MediaType.APPLICATION_JSON_VALUE)
                .mediaType("exe", MediaType.APPLICATION_JSON_VALUE);
        }
    }
    
    这样框架会把这些扩展名也映射到JSON类型,自然就能正常返回了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:18:04