SpringMVC中放行静态资源的方式和原理

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/>最基本的用法. (具体参考这位大佬的文章: https://www.cnblogs.com/dflmg/p/6393416.html )

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值