《Head First JSP与Servlet》中Servlet转发到JSP的斜杠路径困惑
关于Servlet转发路径中前导斜杠的核心歧义解释
你遇到的困惑本质是把两套完全独立的路径解析规则搞混了——前导斜杠在「服务器端内部转发」和「客户端请求跳转」两个场景下,基准路径完全不一样,并没有统一的语义。
两类场景下前导斜杠的真实规则
1. 服务器端请求转发(RequestDispatcher.forward / include)
这类操作是容器在内部完成资源跳转,不会和浏览器产生交互,路径是给服务器内部做资源查找用的:
- 前导斜杠
/代表当前Web应用的根目录,而不是全局容器的根路径 - 比如你部署的应用上下文路径是
myApp,代码里写的/result.jsp,服务器解析时会自动拼接当前应用的上下文路径,最终查找的资源实际位置就是myApp/result.jsp,也就是你项目根目录下的目标文件,根本不会去全局容器根路径下找result.jsp - 这种场景下写不带斜杠的相对路径
result.jsp时,解析基准是当前请求的资源路径:- 如果你当前请求的是应用根下的Servlet(比如映射为
http://localhost:8080/myApp/TestServlet),相对路径计算出来的结果刚好也是myApp/result.jsp,所以看起来和带斜杠的写法效果完全一样 - 但如果你的Servlet是嵌套在子路径下的(比如映射为
http://localhost:8080/myApp/admin/TestServlet),写相对路径result.jsp就会被解析为myApp/admin/result.jsp,直接找不到目标文件,这时候斜杠的作用就体现出来了
- 如果你当前请求的是应用根下的Servlet(比如映射为
2. 客户端侧跳转(response.sendRedirect / HTML内的链接、表单提交地址)
这类操作是把路径返回给浏览器,由浏览器重新发起HTTP请求,路径是给浏览器解析的:
- 前导斜杠
/才是你之前理解的全局容器根路径,也就是从http://localhost:8080/开始计算的路径 - 比如在这个场景下写
/result.jsp,浏览器真的会请求http://localhost:8080/result.jsp,这时候因为这个路径下根本没有你项目的资源,就会返回404,必须手动补上应用名写成/myApp/result.jsp才能正常访问
为什么会出现认知矛盾
很多教程和书籍没有特意明确区分这两套规则:
- 书中提到的「前导斜杠路径不附带应用名」,说的是客户端侧跳转的规则
- 但书中举的转发用
/result.jsp的示例,用的是服务器端的路径解析逻辑 - 如果示例本身是把应用部署为全局根上下文(也就是应用名直接为
/,访问时不需要带myApp),那么两类场景下的路径解析结果会完全重合,作者就更不会特意点明规则差异,最终让读者误以为前导斜杠在所有场景下都是同一个语义。
简单总结:只要是Java代码里写的、给服务器内部做转发用的路径,斜杠开头的基准永远是当前应用根;只要是写给浏览器、让浏览器发请求用的路径,斜杠开头的基准永远是容器全局根。
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

