SpringMVC-访问静态资源的问题

先总结下DIspatcherServlet的映射路径问题。

DispatcherServlet的映射路径

DispatcherServlet的拦截路径(<url-pattern>)一般指定为/,这时DispatcherServlet会拦截除.jsp.jspx为后缀的请求外的所有请求。这是因为Tomcat中配置了一个jsp servlet,如下(在tomcat安装目录下的config/web.xml):

<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>
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

  • 因为*.jsp *.jspx的匹配度比/高,所以访问jsp的请求将不会被映射路径为/的DispatcherServlet拦截,而是被jsp servlet拦截
  • 但如果是访问.html .css等其他静态资源,因为tomcat的deafult servlet的映射路径(默认是/)会被DispatcherServlet覆盖掉(映射路径为/时),所以访问这些静态资源的请求会被DispatcherServlet拦截,且会造成无法访问到静态资源。原因如下:
    • DispatcherServlet会把匹配到的所有请求都当做是对控制器的访问,去掉后缀进行匹配,若匹配不到控制器的方法,则会报404错误。例如访问/main.css会变成/main这就造成.html.jpg等静态资源无法被直接访问,在html中引用.css或.js文件也会失效

DispatcherServlet的另一种映射路径是*.do,这样配置只会拦截以.do的请求,可以正常访问静态资源。

但若是要使用rest风格,则要使用/

为了能直接访问静态资源,可以使用SpringMVC提供的<mvc:default-servlet-handler />标签。见下文。

mvc:default-servlet-handler标签

在springmvc的配置文件中使用<mvc:default-servlet-handler />标签,可以解决上述无法访问静态资源的问题。

使用该标签时SpringMVC会创建一个DefaultServletHttpRequestHandler,其相当于一个controller,映射路径是/**,且它的优先级在所有控制器中的最低的,即当一个请求匹配不到其他所有控制器时,就会被DefaultServletHttpRequestHandler处理,它会把这些请求扔给tomcat的default servlet处理。从而可以访问到web应用中的静态资源

另一种解决方法是配置tomcat的default servlet的映射路径(不用配置<servlet>标签,因为该servlet在tomcat中被配置),让对应的静态资源被default servlet拦截:

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.html</url-pattern>
</servlet-mapping>

参考

DispatcherServlet url-pattern中 /、/*、*.do中的区别与作用

Spring关于Default Servlet的官方文档

posted @ 2020-09-27 17:36  bxxiao  阅读(289)  评论(0)    收藏  举报