【JavaWeb】Web 中访问资源路径问题汇总
Web中 / 斜杠的不同意义
- 浏览器内代表所有资源:
/**
- 服务器内代表所有资源:
/
在Web中,/ 是绝对路径:
- / 如果被浏览器解析,得到的地址是:
http://ip:port/
(指写在静态html代码中,无法被服务器解析,只能被浏览器解析)
1 | <a href="/">斜杠</a> |
- / 如果被服务器解析,得到的地址是:
http://ip:port/工程路径/
1 | // 映射 |
- 特殊情况:
response.sendRedirect("/");
会将斜杠发送给浏览器解析,得到http://ip:port/
,因此需要再加上工程名response.sendRedirect("/projectName/xxx");
/WEB-INF/目录下的资源文件,客户端无法直接访问(即不能在浏览器中输入url直接跳转),而只能在servlet程序中跳转
在IDEA中,"/“代表的项目文件路径为”target/项目名-1.0-SNAPSHOT/
"
在Web应用的前端程序(.jsp)中:
- 不以 / 开始的相对路径找资源时以当前资源的路径为基准,容易出现问题(不推荐使用)
- 以 / 开始的相对路径找资源时以
http://ip:port/
为基准,不包含当前项目名称路径,因此需要在资源前加上${pageContext.request.contextPath}/
以使程序能找到"target/项目名-1.0-SNAPSHOT/
"下的资源文件(项目名-1.0-SNAPSHOT
为Maven工程打包后生成的工程根目录)。例如若想在.jsp文件中引入css文件的路径,需要写href="${pageContext.request.contextPath}/css/style.css"
Spring MVC资源路径映射
在Spring MVC的web.xml
中配置路径时,常用 /
1 | <!-- / 匹配所有的请求;(不包括.jsp)--> |
注意点:
/
不会匹配 .jsp/*
匹配所有的请求,包括 .jsp
*.jsp
由Tomcat负责处理,不需要SpringMVC拦截处理。因此常用 /
原因分析
所有JavaWeb项目里的web.xml
都继承自Tomcat的父web.xml
,其内配置了一个默认的DefaultServlet:
1 | <servlet> |
DefaultServlet是Tomcat用于处理静态资源(除了jsp和servlet之外都是静态资源)的处理器,当DefaultServlet判断得知url中访问的是静态资源文件时,就会直接去服务器目录下找该资源是否存在。其配置了url-pattern:/
而Spring MVC中我们同样配置了url-pattern:/
,因此会覆盖Tomcat中的DefaultServlet,使得静态资源不能被Tomcat里的DefaultServlet所处理,只能被我们配置的DispatcherServlet拦截处理。静态资源被DispatcherServlet拦截时会判断哪个方法的@RequestMapping
是这个静态资源,显然并不能找到,因此无法正常显示。
*.jsp
处理问题:Tomcat里的web.xml中配置了对jsp文件的处理,该处理器将处理jsp文件:
1 | <servlet-mapping> |
若我们在SpringMVC配置中只添加url-pattern:/
而没有添加url-pattern:*.jsp
,则将只覆盖父web.xml里的url-pattern:/
(处理静态资源),并没有覆盖url-pattern:*.jsp
。因此这种情况下,遇到jsp文件,则由Tomcat里的默认处理器处理;遇到普通请求,由DispatcherServlet处理;遇到静态资源,因覆盖了Tomcat,则无法处理。
若配置url-pattern:/*
,则所有请求资源都将被拦截处理。
因此,若想在使用Spring MVC的DispatcherServlet的同时仍能处理静态资源,则需要添加:
1 | <mvc:default-servlet-handler/> |
其能将Spring MVC无法处理的请求交给Tomcat默认的Servlet处理,让Spring MVC不处理静态资源。