spring mvc对静态资源的访问

 如果我们的项目使用的是springmvc,在web.xml中会有一段这的配置。

  

<servlet>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:ApplicationContext-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

  其中的DispatcherServlet会拦截一切(<url-pattern>/</url-pattern>)请求,当然也包含静态请求(html,js,css,img等),注意jsp文件不是静态资源。其本质还是一个servlet。我们知道DispatcherServlet拦截完请求以后会交给对应的controllers的requestmapping来处理。那么如果是静态资源该如何处理呢?

  举个例子:假设我再webapp根目录下新建了一个index.html文件,而我在某个controllers类下也有一个逻辑名称为index.html的方法。如下所示。

    @RequestMapping("index.html")
    public ModelAndView index() {
        ModelAndView mv = new ModelAndView("back/main/Login");
        return mv;
    }

  运行项目,在浏览器地址栏输入localhost:8080/warrior/index.html。则会去执行public ModelAndView index()的代码。

  假如我把这个方法注释掉呢?继续运行localhost:8080/warrior/index.html。则会报404错误。

  这是因为spring mvc还是把这个请求地址当成一个逻辑视图地址,而去controllers类中寻找关联这个地址的方法,但是找不到,所以报404了。

  我们怎样能让spring mvc识别静态文件以规避这个错误呢?有两种方法。

  1.使用<mvc:default-servlet-handler/>

  在mvc的配置文件中,加入以下两句代码。

  

  <mvc:annotation-driven/>
    <!-- 静态资源访问方式一,推荐使用 -->    
    <mvc:default-servlet-handler/>

 在web.xml中的DispatcherServlet配置前面加上如下代码:

     <!-- 对静态资源的配置 -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
        <url-pattern>*.css</url-pattern>
        <url-pattern>*.ico</url-pattern>
        <url-pattern>/img/*</url-pattern>
         <url-pattern>/static/*</url-pattern>
        <url-pattern>/fonts/*</url-pattern>
        <url-pattern>/font/*</url-pattern>
    </servlet-mapping>

这样配置了以后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。

  需要注意的是,这两句必须一同出现,如果没有<mvc:annotation-driven/>这句,会访问不到controllers中的方法。

  2.使用 mvc:resources来区分静态资源

  为了将静态资源与动态资源进行区分,spring mvc使用<mvc:resources mapping="/**" location="/,/admin/" />这样的配置来标明静态资源所在的路径。

  以上述那条语句为例:当我们访问localhost:8080/warrior/index.html的时候,spring mvc先去寻找逻辑名为“index.html”的action,找不到的话,再去location为/,也就是根目录下的index.html,如果还是找不到的话,再去寻找admin/目录下的index.html。而不会报错。

  我的理解是,mvc:resources为静态资源定义了一个逻辑名称,或者说映射(mapping),当我们需要访问静态资源的时候,就无需再使用物理地址了,直接使用映射地址就好了。

  使用mvc:resources的好处除了创建一个别名以外,是不用再创建一个servlet,不像方法一,而且他可以随意指定静态资源的位置,甚至可以放在web-inf下面。另外,还可以对静态资源做一些配置,好充分利用缓存。

  看几个mvc:resources的例子:

    <mvc:resources mapping="/**" location="/,/admin/" /><!-- 当访问warrior/demo/index.html时候,先到根目录下去寻找demo/index.html,再到admin目录下去寻找demo/index.html -->
    <mvc:resources mapping="/admin/**" location="/,/admin/" /><!-- 当访问warrior/static/index.html时候,先到根目录下寻找index.html,再到static下寻找index.html --> 

  PS:当上述两种配置同时出现在spring mvc的配置文件中,顺序是,先去controllers中寻找,找不到再使用<mvc:default-servlet-handler/>去寻找静态资源,找不到就会报404,不会再使用mvc:resources去寻找了。

  

原文地址:https://www.cnblogs.com/roy-blog/p/7992373.html