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的自动解码干扰

相关推荐
开开心心就好5 分钟前
以图搜图找重复图片,本地工具离线就能用
javascript·智能手机·ffmpeg·c#·ocr·word·音视频
IT_陈寒10 分钟前
SpringBoot自动配置的坑我帮你踩过了
前端·人工智能·后端
代码山河11 分钟前
Java的前世今生:从Oak语言到Java 23的发展史
java·学习·架构·教程·面向对象·项目
vx_Biye_Design12 分钟前
springboot角色扮演服务平台65161-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计
李游Leo13 分钟前
HarmonyOS 7 QuickDock 闪控窗开发实录 02:floatView × floatingBall:形态切换、位置恢复与单一状态源【鸿蒙心迹】
java·华为·harmonyos
企业数字化笔记14 分钟前
视频局部合成怎么做得自然?掩膜修复、边缘羽化、时序稳定与背景替换
java·javascript·音视频
仍然.20 分钟前
Redis---主从复制
java·数据库·redis
vx_Biye_Design24 分钟前
springboot咖啡厅顾客点单管理系统12080-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
QQ_216962909627 分钟前
基于微信小程序的智能膳食分析系统
java·大数据·spring boot·微信小程序·小程序·旅游
海绵宝宝转agent31 分钟前
Leetcode100 二叉树的中序遍历
java·算法