处理REST API中的特殊字符

4

我有以下URL:

http://context_path/info/abc/def

这会被转换为

http://context_path/info/abc%2Fdef

我的控制器映射如下:

@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)

这里的 'id' 包含斜线 (/)。因此,当我访问URL时,会出现 400 Bad Request 错误。

我知道可能的解决方案:

  • 设置tomcat允许斜线。
  • 使用URL编码。
  • 使用@RequestParam而不是@PathVariable

但以上解决方案对我来说都不可行。

Q. 是否有其他解决方案(如使用正则表达式或更改映射或其他任何方法)来解决问题? 此外,Tomcat如何正确处理其他特殊字符('.','''',':',','),使控制器得到响应,但'/'却无法得到响应。

已尝试但未能解决问题:

1) @RequestMapping(value = "/info/{id:.*}", method = RequestMethod.GET)
2) @RequestMapping(value = "/info/{id}/**", method = RequestMethod.GET)
3) @RequestMapping(value = "/info/**", method = RequestMethod.GET)

可能是重复的问题,参见 使用Spring 3 RequestMapping注解匹配“URL的其余部分” - user1211
但是为什么你的ID值中有一个斜杠呢? - ScanQR
@TechBreak 我知道这是不正确的,但我正在使用旧值进行工作,而且我无法修改它们。 - SuhasD
@user3632894 尝试了两种方法,但都没有起作用。 - SuhasD
@SuhasD,只是想澄清一下,您是否有能力在客户端上处理URL并调用服务器? - ScanQR
@TechBreak 我更倾向于使用服务器端解决方案而非客户端-服务器解决方案。 - SuhasD
3个回答

1

虽然不太好,但你可以使用Base64转换

这样,你的客户端将发送一个编码后的id,你需要在控制器中对其进行解码。

import org.apache.commons.codec.binary.Base64;

@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public String get(@PathVariable String id) {
    final String realId = new String(new Base64(true).encodeBase64URLSafe(id));
    [...]
}

编辑:您应该使用 Base64 的url保存实现


这样行不通。Spring将解码或取消转义映射URL,然后尝试基于生成的URL调用处理程序方法。因此它会返回错误请求。 - ScanQR
@TechBreak 你试过了吗?我正在尝试并且它可行。 - dieter
@dit Base64工作正常,但如果ID包含'?',它会将其转换为'/'。有没有其他编码器不使用'/'进行编码的? - SuhasD
1
@SuhasD 使用Apache的URL save base64实现:https://dev59.com/c2035IYBdhLWcg3wE7xr - dieter
1
@dit 新的Base64(true)对我很有效。谢谢。我使用.encodeBase64URLSafe()方法代替了仅使用.encode()方法,以去除"\r"和"\n"。 https://dev59.com/wWIj5IYBdhLWcg3wuXWN#37734981 - SuhasD

0
您可以使用类似以下的代码: 如何处理包含斜杠(/)的请求?

但它也有其局限性,我建议在调用 api 时将斜杠替换为其他字符(如#),然后在 rest 控制器中处理它之前再将其替换回来。
如果在调用 api 时无法替换,则可以使用筛选器并在那里替换数据。

-1

我添加了以下正则表达式[\[\]A-Za-z0-9 "',():._^-]+。它适用于除'/'之外的所有其他特殊字符,如果我修改上述正则表达式为[\/\[\]A-Za-z0-9 "',():._^-]+,那么没有URL可以工作(即使是那些使用旧的正则表达式也无法工作)。 - SuhasD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接