首页 > 解决方案 > 包含反斜杠引号的 @PathVariable 返回 400 Bad Request

问题描述

如果您使用 Spring Boot (2.5.3) 运行这个简单的 RestController:

@RestController
public class SampleRestController {

    @GetMapping("/search/{criteria}")
    public String hello(@PathVariable(name = "criteria") String criteria) {
        return "Hello: " + criteria;
    }

}

并尝试在浏览器中打开此链接:

 http://localhost:8080/search/%22%5C%22bug%5C%22%22 

然后你会得到嵌入式 Tomcat 返回的“400 Bad Request”。

我不明白,这是Tomcat中的错误吗?这不是有效的 URL 吗?

编辑:根据一些回复:我逐步浏览了 Tomcat 9.0.50 源代码,并看到了关于 ALLOW_BACKSLASH 的行。值 true 或 false 对我都没有好处,因为用 true 替换\/false,它返回 400 Bad Request。我需要的是允许反斜杠而不用斜杠替换它。

我的问题真的是这是否是 Tomcat 中的错误,因为对我来说 URL 似乎是有效的。从技术上讲\,我并没有在 URL 中添加一个,而是添加了一个 % 编码的反斜杠。如果不允许用户在 URL 中发送任何字符,那么 %-encoding 的目的是什么?

标签: spring-mvctomcat

解决方案


请参阅上面的 Piotr P. Karwasz 评论以获得更好的解释。

对应Spring Boot(2.5.3)的tomcat版本是9.0.50。通过查看源代码CoyoteAdaptorTomcat 系统参数文档ALLOW_BACKSLASH,通过 System Property的标志配置 url 检查org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH,并使用false默认值。

...
    protected static final boolean ALLOW_BACKSLASH =
        Boolean.parseBoolean(System.getProperty("org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH", "false"));

...

要在 URL 中允许反斜杠,我们可以在运行应用程序时添加以下内容。

-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true

此属性在tomcat 10.0.0-M4之后被替换。

删除 org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH 系统属性,替换为连接器上的 allowBackslash 属性。(雷姆)


推荐阅读