在使用 SpringMVC 的 @RequestMapping 的时候, 碰到了 404, 某篇博客的解决办法为如下:
抱着试一试的态度, 确实可以解决, 想了想为什么, 先描述下我遇到的情况:
在没加 ‘/’ 之前的 类级别的 请求路径为:
@RequestMapping(path = "/spittle")
视图解析器配置:
InternalResourceViewResolver internalResourceViewResolver =
new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("WEB-INF/views/"); //注意此处没有添加 ' / '
internalResourceViewResolver.setSuffix(".jsp");
internalResourceViewResolver.setExposeContextBeansAsAttributes(true);
处理方法为:
@RequestMapping(method = RequestMethod.GET)
public String spittles( ) {
return "spittles";
}
此时可以成功的请求, 注意此时并没有在 WEB-INF 前面添加 /, 但是仍然可以请求成功, 具体原因后面解析
重点:
此时将类级别上的 @RequestMapping 改成如下;
@RequestMapping(path = "/spittle/hello")
即增加了后缀路径 /hello, 其他的不变, 这个时候就报 404 了!!!
错误如下:
仔细看红色部分, 我们发现在 spittle后面添加的 “/hello” 路径不见了, 被替换成了 WEB-INF… 路径.
到这里, 如果读者对 Servlet 的请求转发机制中 相对URL和绝对URL 了解的话, 应该就恍然大悟了.
我们知道, 在 springMVC 内部, 对请求控制权的转移显然是通过请求转发来实现的, 而在 Servlet 的请求转发的过程中, 可以使用 相对 URL 和绝对 URL, 绝对 URL 较为简单, 关键在于相对 URL, 有两种情况:
- 相对 URL 以 ‘/’ 开头
- 相对 URL 不以 ‘/’ 开头.
这两种的区别为, 以 http://localhost:8080/MavenWebDemo/spittle/hello 为例, 其中 MavenWebDemo 为项目名称:
-
如果使用 以 ‘/’ 开头的 WEB-INF/views/ 相对 URL, 转发后的路径为 : http://localhost:8080/MavenWebDemo/WEB-INF/views/
-
如果不使用 ‘/’ 开头的相对URL, 替换后的路径为: http://localhost:8080/MavenWebDemo/spittle/WEB-INF/views/
此时回到报错 404 的问题上:
第一次的请求路径为 http://localhost:8080/MavenWebDemo/spittle , 没有给 视图解析的中的 “WEB-INF” 前缀添加 ‘/’, 因此, 在 spring 内部进行请求转发后的 路径为:
http://localhost:8080/MavenWebDemo/WEB-INF/views/spittles.jsp
我们知道, WEB-INF 目录一般都是直接位于项目的根目录下, 此时的路径显然是正确的.
第二次添加了 /hello 后缀后,即: http://localhost:8080/MavenWebDemo/spittle/hello 如果仍然不给视图解析器添加以 ‘/’ 开头的 “WEB-INF” 配置前缀, 那么根据相对 URL 替换原则, 替换后的路径为:
http://localhost:8080/MavenWebDemo/spittle/WEB-INF/views/spittles.jsp
也就是上图中红色部分的路径, 很显然, 在 spittle 目录下根本不存在 WEB-INF 目录,
此时必报错 404! 因此也就可以解释为什么需要在 "WEB-INF"前面添加 ‘/’ 了!!!
参考博文: https://blog.youkuaiyun.com/noaman_wgs/article/details/52904187