springboot对于@PathVariable自动解码问题

复制代码
@GetMapping("/getFile/{key}")
public void filePreview(@PathVariable("key") String key, HttpServletResponse response) {

}

测试如下:

复制代码
// 源字符串(urlencode前)A:MwbR64EbzUpX5MDnA3qb8yiTXUlbPegQqiNxuT8m7lbJ/k5THwkM+UvaRWWd7PzFVdZoGHx/GEPxm75LJZxKq1fqCdr3PKT/5P7qqoZm9AbN4n4kZ/z9uA==
// urlencode后  B: MwbR64EbzUpX5MDnA3qb8yiTXUlbPegQqiNxuT8m7lbJ%2Fk5THwkM%2BUvaRWWd7PzFVdZoGHx%2FGEPxm75LJZxKq1fqCdr3PKT%2F5P7qqoZm9AbN4n4kZ%2Fz9uA%3D%3D  (/变成了%2F,+变为%2B,=变成%3D)
//对传入的B字符串 springboot自动解码后 C:MwbR64EbzUpX5MDnA3qb8yiTXUlbPegQqiNxuT8m7lbJ%2Fk5THwkM+UvaRWWd7PzFVdZoGHx%2FGEPxm75LJZxKq1fqCdr3PKT%2F5P7qqoZm9AbN4n4kZ%2Fz9uA==(和原来的不太一样%2F没有解码成/)
// srpingboot自动解码后的C字符串 再 使用urldecode decode后的 D: MwbR64EbzUpX5MDnA3qb8yiTXUlbPegQqiNxuT8m7lbJ/k5THwkM UvaRWWd7PzFVdZoGHx/GEPxm75LJZxKq1fqCdr3PKT/5P7qqoZm9AbN4n4kZ/z9uA==   %2B 解码变成了空格了
//没有自动解码直接decode,也就是对 B 直接解码后  E:MwbR64EbzUpX5MDnA3qb8yiTXUlbPegQqiNxuT8m7lbJ/k5THwkM+UvaRWWd7PzFVdZoGHx/GEPxm75LJZxKq1fqCdr3PKT/5P7qqoZm9AbN4n4kZ/z9uA==  (这个和源字符串一致)
//将springboot自动解码后的字符串中+替换成%2B再解码:MwbR64EbzUpX5MDnA3qb8yiTXUlbPegQqiNxuT8m7lbJ/k5THwkM+UvaRWWd7PzFVdZoGHx/GEPxm75LJZxKq1fqCdr3PKT/5P7qqoZm9AbN4n4kZ/z9uA==(和源字符串一致)-->最终解决方案

Spring Boot在处理 @RequestParam@PathVariable 等注解时,默认会自动进行一次URL解码。但它的解码方式取决于容器和版本,有时会出现:

  • %2F 没有被解码(出于安全考虑,防止路径遍历攻击)

  • %2B 被解码成了空格(+ 在URL编码的 application/x-www-form-urlencoded 中确实代表空格)

key如果包含特殊字符,必须进行urlencode,但springboot接收时会自动对key进行decode的,但测试发现有些字符串并没有decode,而且代码如果直接decode这个自动解码后的字符串解码出来的字符串可能包含空格!

  • URLDecoder.decode()默认将+转为空格,但保留%20为空格

  • Spring的@PathVariable默认将%20转为空格,但保留+为加号

URL编码规则很明确:

  • 只有空格 会被编码为 %20+

  • 其他字符(如字母、数字、中文等)都会编码为 %XX 形式

  • 解码时,%20+ 才会被转回空格

方案一:获取原始参数值(推荐)

如果你需要自己完全控制解码过程,可以直接获取原始请求参数,避免Spring Boot的自动解码干扰

相关推荐
Bigger16 小时前
Tauri (26)——托盘图标总对不上系统主题?一行 Template Image 搞定
前端·rust·app
To_OC16 小时前
从一次栈溢出报错说起,我把递归彻底扒明白了
javascript·算法·程序员
kyriewen18 小时前
面试官问你:“AI 能写 80% 的代码了,公司为什么还需要你?”
前端·javascript·面试
甲维斯19 小时前
又升级咯!坦克大战2026,科技与复古并存!
前端·人工智能·游戏开发
Goodbye21 小时前
从 Token 到 Embedding:LLM 核心基础深度解析
javascript·人工智能
用户9385156350721 小时前
工具调用背后:LLM 如何突破“缸中大脑”,操控真实世界?
javascript·人工智能
Goodbye21 小时前
从函数到智能:LLM Tool Use 深度解析
javascript·人工智能
半个落月21 小时前
大模型到底是怎么“调用工具”的?从一个 Node.js Demo 看懂 Tool Use
javascript·人工智能
搬砖的码农21 小时前
(08)为什么我的 Agent 一跑后台服务就卡死
前端·agent·ai编程