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

相关推荐
denlaku12 分钟前
JDK 22 新特性详解
java·开发语言
余槐i17 分钟前
开虚拟线程后接口反而更慢:JDK 21 synchronized 锁住载体线程的排查
java·spring boot·redis·mysql·性能优化
Mr.Pascal19 分钟前
Javascript之什么是作用域?
javascript·1024程序员节
microrain1 小时前
设备报文怎么变,SagooIoT 只约定三个函数名
javascript·物联网·golang·sagooiot
思码梁田1 小时前
CSS 浏览器厂商前缀:从「写 5 遍」到现代自动化兼容
前端·css·css3·border-radius·1024程序员节·box-shadow·厂商前缀
Sirens.1 小时前
网络通信基础:IP、端口、协议分层与数据封装
java·网络·网络协议·tcp/ip·java-ee·1024程序员节
Bug收容所1 小时前
Vue+JS Day3
前端·javascript·vue.js·前端框架·1024程序员节
CRMEB系统商城1 小时前
服装连锁的导购分销与企微私域
java·大数据·开发语言·人工智能·小程序·php·1024程序员节
iCxhust1 小时前
如何实时同步自己的工作日志,在不同的设备间
前端·软件工程·1024程序员节·同步日志