目录
- SpringMVC中放行静态资源的方式和原理
- 1. Servlet的访问路径: url-pattern标签
- 2. Servlet访问路径的分类
- 3. DispatcherServlet的访问路径以及静态资源放行
SpringMVC中放行静态资源的方式和原理
1. Servlet的访问路径: url-pattern标签
- 该标签用来指定servlet的访问路径, 这个路径又被叫做"虚拟路径"或"映射路径", 这个路径必须以"/"开头, 否则服务器启动失败.
- 一个
<servlet-mapping>
中能配置多个<url-pattern>
标签, 这多个路径都映射到同一个Servlet,例如:
<servlet>
<servlet-name>BServlet</servlet-name>
<servlet-class>cn.king.servlet.BServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BServlet</servlet-name>
<url-pattern>/BServlet</url-pattern>
<url-pattern>/bServlet</url-pattern>
<url-pattern>/bservlet</url-pattern>
</servlet-mapping>
我们访问
http://localhost:8080/webapp/BServlet http://localhost:8080/webapp/bServlet
http://localhost:8080/webapp/bservlet
访问的都是cn.king.servlet.BServlet.
由于早期没有过滤器, Servlet就充当了Filter, 因此可以给一个Servlet配置多个url-pattern, 用来拦截多条请求.
2. Servlet访问路径的分类
- Servlet的访问路径有4种配置方式: 精确匹配, 路径匹配, 扩展名匹配, 缺省匹配.
<!--精确匹配, 只有访问"/BServlet"才能访问到该Servlet-->
<url-pattern>/BServlet</url-pattern>
<!--路径匹配, 访问"/user/1","/user/2"等类似url才能访问到该Servlet-->
<url-pattern>/user/*</url-pattern>
<!--下面的配置也属于路径匹配-->
<url-pattern>/*</url-pattern>
<!--扩展名匹配, 访问"add.do","update.do"等类似url才能访问到该Servlet-->
<url-pattern>*.do</url-pattern>
<!--
缺省匹配, 这种匹配的优先级顺序最低, 如果请求没有与之匹配的Servlet,
那么最后, 配置了"/"的Servlet来处理该请求.
-->
<url-pattern>/</url-pattern>
- 注意, 通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符。例如:"/*.do" 就
是错误的,因为星号出现在URL的中间位置上了。"."也是不对的. - 注意,通配符是一种模糊匹配URL的方式,如果存在更具体的
<url-pattern>
,那么访问路径会优先去匹配
更具体的<url-pattern>
例如:
<servlet>
<servlet-name>hello1</servlet-name>
<servlet-class>cn.king.servlet.Hello1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello1</servlet-name>
<url-pattern>/servlet/hello1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>hello2</servlet-name>
<servlet-class>cn.king.servlet.Hello2Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello2</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<!--
当访问路径为http://localhost:8080/webapp/servlet/hello1时,因为访问路径即匹配
hello1的<url‐pattern>,又匹配hello2的<url‐pattern>,但因为hello1的<url‐pattern>
中没有通配符, 相对来说更精确, 所以优先匹配, 即会访问cn.king.servlet.Hello1Servlet。
-->
3. DispatcherServlet的访问路径以及静态资源放行
- 在
%tomcat%/conf/web.xml
中, 有一个DefaultServlet, 她的<url-pattern>
配置的就是"/"
.
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
“/“这个访问路径的匹配优先级最低, 用户发送一个请求, 进行精确匹配->路径匹配->后缀名匹配
后 如果还没有与之对应的Servlet, 那么就会进行缺省匹配, 就会匹配”/”, 就会执行tomcat的web.xml中配置的这个DefaultServlet. 这个Servlet的作用就是根据用户请求, 读取web项目根目录
下的静态资源, 然后将静态资源输出到浏览器, 如果找不到这个静态资源, 就在页面上显示404.
注意, %tomcat%/conf/web.xml
文件是我们编写的所有web项目的web.xml文件的"父文件", web项目启动, 先读取%tomcat%/conf/web.xml
文件, 再读取我们项目中的web.xml文件, 共同作为该web项目的配置. 我们的web.xml中的配置, 可以覆盖%tomcat%/conf/web.xml
中的配置.
那么, 我们自定义的Servlet的<url-pattern>
如果也设置为"/", 那么就会覆盖DefaultServlet.
SpringMVC的前端控制器DispatcherServlet就是这样做的! 我们经常将DispatcherServlet的<url-pattern>
设置为"/", 由于SpringMVC项目中, 在web.xml中只配置了一个Servlet, 那就是DispatcherServlet, 并且DispatcherServlet的<url-pattern>
为"/", 因此即便"/“的优先级最低, 所有的请求也都会匹配到”/", 这就保证了所有的请求都会执行DispatcherServlet.
初学者经常将SpringMVC的前端控制器的DispatcherServlet的访问路径配置为" /* “, 实际上这属于上述说的路径匹配. 如果我们将自定义的Servlet的访问路径配置为” /* “, 那么访问任意路径都能访问到这个Servlet. 但是在DispatcherServlet中, 我们不能将访问路径配置成” /* ", 否则请求"xxx.jsp"不会进入DispatcherServlet.
在SpringMVC中, 无论是把DispatcherServlet的访问路径配置成" / “还是配置成” /* ", 都会拦截静态资源, 也就是说静态资源(js,img,js,css,mp3…)都会走DispatcherServlet, 我们需要单独配置放行静态资源, 即让用户发送的静态资源请求不走DispatcherServlet. 在SpringMVC中放行静态资源有两种方式, 我们常用的一种是在SpringMVC的配置文件spring-mvc.xml
中添加这条配置: <mvc:default-servlet-handler/>
. 添加了这条配置后, 会在Spring MVC上下文中定义一个
org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器(tomcat)默认的Servlet即DefaultServlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
另外, 在SpringMVC中, 还有一种放行静态资源的方式, 如下:
<!--用户请求中带有"/js/", 直接去"webapp/js/**"文件夹下找,而不会走DispatcherServlet-->
<mvc:resources mapping="/js/" location="/js/**"/>
<!--用户请求中带有"/css/", 直接去"webapp/css/**"文件夹下找,而不会走DispatcherServlet-->
<mvc:resources mapping="/css/" location="/css/**"/>
实际上<mvc:resources/>
标签的功能比mvc:default-servlet-handler/>
标签的功能更强大, 上述的例子只是<mvc:resources/>
最基本的用法.