springboot中处理URL中参数有#号的解决方案
“#”是 URL 的片段分隔符,浏览器/HTTP 客户端不会把它原样发给服务端。要想放到路径变量里,必须在客户端把 “#” 做 URL 编码成 “%23”。Spring 会自动解码,还原成原始的 “#”。 服务端(保持 PathVariable,最好放开匹配)
- // 接收 n3map#33#fff#002(客户端需把 # 编码为 %23)
- @PutMapping("/api/redisbin/{key:.+}")
- public ResponseEntity<Void> put(@PathVariable String key, @RequestBody byte[] body) {
- // key 将是 "n3map#33#fff#002"
- ...
- }
- @GetMapping("/api/redisbin/{key:.+}")
- public ResponseEntity<byte[]> get(@PathVariable String key) {
- ...
- }
复制代码客户端怎么传 - # 注意把 # 编成 %23,或用工具编码
- curl -X PUT --data-binary @n3.map "http://localhost:8080/api/bin/n3map%2333%23fff%23002"
- curl -o out.map "http://localhost:8080/api/bin/n3map%2333%23fff%23002"
复制代码- String key = "n3map#33#fff#002";
- // 构建并编码 URI
- URI putUri = UriComponentsBuilder
- .fromHttpUrl("http://localhost:8080/api/bin/{key}")
- .buildAndExpand(key)
- .encode() // 这里会把 # 编成 %23
- .toUri();
- rt.exchange(putUri, HttpMethod.PUT, req, Void.class);
- URI getUri = UriComponentsBuilder
- .fromHttpUrl("http://localhost:8080/api/bin/{key}")
- .buildAndExpand(key)
- .encode()
- .toUri();
- ResponseEntity<byte[]> resp = rt.getForEntity(getUri, byte[].class);
复制代码提示 - 不管放在路径还是查询参数里,“#”都必须先编码(%23);否则会被当作 URL 片段并在请求时被截断。
- 如果不想处理特殊字符,考虑把 key 做一次 Base64/URL-safe 编码再传。
|