• Spring MVC中处理静态资源的多种方法


    处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了。

    因为一个网站的显示肯定会依赖各种资源:脚本、图片等,那么问题来了,如何在页面中请求这些静态资源呢?

    还记得Spring MVC中的DispatcherServlet吗?它是Spring MVC中的前置控制器,若配置的拦截路径为“/”,那么所有的请求都将被它拦截。对静态资源的访问也属于一个请求,那么也会被它拦截,然后进入它的匹配流 程,我们知道它是根据HandlerMapping的配置来匹配的。而对于静态资源来说,默认的Spring MVC是没有注册匹配规则的,此时若你去请求一个静态资源,则会报404错误。

    如何处理静态资源的请求呢?

    根据上面介绍的,我们可以配置一个处理静态资源的HandlerMapping

        <bean id="resourceHttpRequestHandler" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">  
            <property name="locations" value="classpath:/META-INF/resources/"></property>     
        </bean>  
          
        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
            <property name="mappings">  
                <props>  
                    <prop key="/resources/**">resourceHttpRequestHandler</prop>  
                </props>  
            </property>  
        </bean>  


    其中ResourceHttpRequestHandler就是处理静态资源请求的类,当然如果你愿意,也可以自己尝试写一个。

    不过现在这样自己写SimpleUrlHandlerMapping比较少了吧,项目中都是采用的注解配置,只不过是将匹配关系放到注解上

    另外,还可以使用mvc命名空间的resources标签来配置

        <mvc:resources mapping="/resources/**" location="/resources/" />  


    本质上也是把ResourceHttpRequestHandler注册到SimpleUrlHandlerMapping上。

    还有别的方法来处理静态资源请求吗?

    Spring MVC还提供了一个配置项:mvc:default-servlet-handler

    这个标签对于匹配规则为"/"的DispatcherServlet才生效(因为别的匹配规则一般也不会拦截静态资源)。它会为DefaultServletHttpRequestHandler配置上"/**"的拦截规则和最低的匹配优先级。

    DefaultServletHttpRequestHandler处理请求时会将其全部转发到容器的DefaultServlet上。因此它在 HandlerMapping必须是优先级最低的。如果你使用<mvc:annotation-driven>或你使用了自定义的 HandlerMapping实例,确保它们的order值比DefaultServletHttpRequestHandler小 (Integer.MAX)。

    另外需要注意的是,这里寻找容器的DefaultServlet是用名字而不是路径。所以首先要搞清楚容器的DefaultServlet的名字, 当然一般主流容器的名字是无需指定的,比如Tomcat, Jetty, JBoss, and GlassFish等。若非常用容器,则可能需要手动指定:

        <mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>  


    这种方式也是依赖于容器的DefaultServlet的,那么我们是否能直接用容器的DefaultServlet来处理静态资源请求,而不是这样先通过Spring MVC来转发呢?(相比性能上会好很多),答案是肯定的。

    比如我们将资源文件都放在resouces目录下,那么只需要在web.xml中配置:

        <servlet-mapping>  
            <servlet-name>default</servlet-name>  
            <url-pattern>/resource/*</url-pattern>  
        </servlet-mapping>  

    并将它放在所有Servlet的最前面(为了让它最先匹配),这样的话性能上应该比较好

    但是这样还会有个问题,就是无法访问到classpath下的资源文件,看了tomcat的DefaultServlet的配置项,似乎也没有可以指定目录的地方。

    所以,综上所述,性能最好的应该是直接利用容器的DefaultServlet,让它最先拦截静态资源请求,这样就避免了后续的转发等操作,提高了 性能,但是无法访问classpath下的资源文件。而通过mvc:resources标签可以简单配置匹配规则和资源文件路径,应该说是最简单快捷的一 种方式,当然这大概也是mvc命名空间设计的初衷。

    另外,若想结合两者的话,自己倒是可以尝试写一个Servlet来处理,不过估计有难度且麻烦。

  • 相关阅读:
    解决ArrayList线程不安全
    TraceView工具的使用
    Service
    Android之移动热修复
    06 swap命令,进程管理,rmp命令与yum命令,源码安装python
    04 linux用户群组和权限
    03 linux命令的操作
    Unity 5.x 导入教学Demo
    Creo二次开发—内存处理
    求一个数的二进制数中所含1的个数的代码实现
  • 原文地址:https://www.cnblogs.com/hyl8218/p/5774664.html
Copyright © 2020-2023  润新知