zoukankan      html  css  js  c++  java
  • springMVC 访问静态资源

    问题描述  

    使用SpringMVC时遇到静态资源无法加载的问题,报404

    问题原因

      如果SpringMVC的映射模式采用的是后缀名匹配,如【*.do】或者【*.action】则不会出现该问题,因为静态资源的访问会由tomcat的默认Servlet,即org.apache.catalina.servlets.DefaultServlet,进行处理。

      出现这种问题一般是在web.xml中的对spring的DispatcherServlet采用了如下配置,即url-pattern设置为了“/”(或"/*",这种匹配默认极其恶劣),这样便要求SpringMVC负责处理静态资源请求。

      

    <!-- Spring MVC servlet -->
        <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:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
            <async-supported>true</async-supported>
        </servlet>
        <servlet-mapping>
            <servlet-name>SpringMVC</servlet-name>
            <!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
            <url-pattern>/</url-pattern>
        </servlet-mapping>

      这种情况下浏览器的jsp请求能够成功是以为Tomcat容器默认配置了jsp Servlet,如下。由于url-pattern是“.jsp”,属于扩展名匹配,优先级高于“/”匹配,所以jsp Servlet会被容器调用,不会出现jsp资源无法获取的问题。

      关于Servlet中url-pattern的配置和优先级问题,请参见博文servlet的url-pattern匹配规则

         <servlet>
            <servlet-name>jsp</servlet-name>
            <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
            <init-param>
                <param-name>fork</param-name>
                <param-value>false</param-value>
            </init-param>
            <init-param>
                <param-name>xpoweredBy</param-name>
                <param-value>false</param-value>
            </init-param>
            <load-on-startup>3</load-on-startup>
        </servlet>
         <!-- The mappings for the JSP servlet -->
        <servlet-mapping>
            <servlet-name>jsp</servlet-name>
            <url-pattern>*.jsp</url-pattern>
            <url-pattern>*.jspx</url-pattern>
        </servlet-mapping>

    解决方法

    1使用tomcat容器的默认servlet 处理静态资源请求

    在web.xml里添加如下的配置,由于后缀名匹配的优先级高于默认匹配规则(“/”),所以静态资源请求会由DefaultServlet进行处理。

    <servlet-mapping>
         <servlet-name>default</servlet-name>
         <url-pattern>*.css</url-pattern>
    </servlet-mapping>
     
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.gif</url-pattern>
    
     </servlet-mapping>
        
     <servlet-mapping>
         <servlet-name>default</servlet-name>
         <url-pattern>*.jpg</url-pattern>
     </servlet-mapping>
        
     <servlet-mapping>
         <servlet-name>default</servlet-name>
         <url-pattern>*.js</url-pattern>
     </servlet-mapping>

    tomcat的default servlet定义如下

    <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>

    在spring的配置文件中添加<mvc:default-servlet-handler/>

    <mvc:default-servlet-handler/>

      注意,需要是spring3.0.5以上版本

      该配置会在DispatcherServlet中注册 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,该类中又注册了访问路径和对应的处理类,如下图:

      /**  ->  org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler

      

      即最终由DefaultServletHttpRequestHandler完成静态资源请求处理。

      这时SpringMVC便具备了处理静态资源请求的能力。

      另外需要注意的是,由于<mvc:default-servlet-handler/> 标签注册了SimpleUrlHandlerMapping类,所以DispatcherServlet便不再默认注册DefaultAnnotationHandlerMapping,也就无法处理RequestMapping等注解。解决方法就是手动在配置文件中配置DefaultAnnotationHandlerMapping bean,或者添加<mvc:annotation-driven/>标签。

    在spring的配置文件中添加<mvc:resources mapping="" location="" />

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

      该标签和<mvc:default-servlet-handler/>类似,也会在DispatcherServlet中注册 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,不同的是每一条配置都会注册一个SimpleUrlHandlerMapping到DispatcherServlet中,上例会注册三个。

    每个SimpleUrlHandlerMapping内部会生成一个映射,如<mvc:resources mapping="/js/**" location="/js/" />对应的SimpleUrlHandlerMapping内部映射为:

    "/js/**" -> "ResourceHttpRequestHandler 

    即最终由ResourceHttpRequestHandler 完成静态资源请求的处理。

    另外需要注意的是,使用<mvc:resources mapping="" location="" />后,也需要手动在配置文件中配置DefaultAnnotationHandlerMapping bean,或者添加<mvc:annotation-driven/>标签。

  • 相关阅读:
    day3-课堂笔记
    day2-作业及答案
    2016年11月19日一周工作知识点总结
    2016年11月19日一周工作知识点总结
    使用JDK开发WebService
    使用JDK开发WebService
    Java WebService 简单实例
    Java WebService 简单实例
    BigDecimal不整除的一个异常java.lang.ArithmeticException
    2016年11月13日周工作知识点总结
  • 原文地址:https://www.cnblogs.com/canger/p/6093452.html
Copyright © 2011-2022 走看看