"问题分析: 1、当我们的 SpringMVC 核心拦截器DispatcherServlet拦截“/”时,所有的请求都会经过拦截器进行匹配,此时静态资源,例如*.css、*.js、*.jpg……就会被拦截器拦下来,导致不能访问,出现 404 问题。 问题的关键就在于我们设置的是/。 DispatcherServlet .."

SpringMVC 中的静态资源映射

问题分析:

1、当我们的 SpringMVC 核心拦截器DispatcherServlet拦截“/”时,所有的请求都会经过拦截器进行匹配,此时静态资源,例如*.css、*.js、*.jpg……就会被拦截器拦下来,导致不能访问,出现 404 问题。

问题的关键就在于我们设置的是/

<!-- 注册 SpringMVC 核心控制器 -->
<servlet>
	<servlet-name>DispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springMVC.xml</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

那么这是为什么呢?为什么/就不能访问静态资源呢?因为: /将所有 url 请求都交给 spring 去处理,但是 spring 认可的 url 请求都在 Controller 中,以注解的方式定义 @RequestMapping(value = “/index”, method = RequestMethod.GET), 这样一来,静态资源的 url 请求不被 spring 认可,就过不了拦截器,那就没法访问了。

2、如果你的 DispatcherServlet 拦截*.action这样的 URL,就不存在访问不到静态资源的问题,那下面的内容,基本上跟你没有关系了。

解决办法一:激活 Tomcat 的 defaultServlet 来处理静态文件

在 web.xml 里添加如下配置

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

注意: : - 要配置多个,每种文件配置一个。

一些其他运行环境的 defaultServlet

运行环境 默认 Servlet 名字
Tomcat, Jetty, JBoss, GlassFish default
Google App Engine _ah_default
Resin resin-file
WebLogic FileServlet
WebSphere SimpleFileServlet

解决办法二:在 spring3.0.4 以后版本提供了<mvc:resources />

<mvc:annotation-driven />

<!-- 静态资源映射 -->
<!--<mvc:resources mapping="/layui/images/**" location="/WEB-INF/static/layui/images/"/>-->
<!--<mvc:resources mapping="/layui/css/**" location="/WEB-INF/static/layui/css/"/>-->
<!--<mvc:resources mapping="/layui/font/**" location="/WEB-INF/static/layui/font/"/>-->
<!--<mvc:resources mapping="/layui/lay/**" location="/WEB-INF/static/layui/lay/"/>-->
<mvc:resources mapping="/layui/**" location="/WEB-INF/static/layui/" />

解释:

: - mapping:映射

它可以把/layui/**映射到ResourceHttpRequestHandler进行处理,location指定静态资源的位置. 可以是 web application 根目录下、jar 包里面,这样可以把静态资源压缩到 jar 包中。cache-period 可以使得静态资源进行 web cache。

如上面代码,实际上,layui 目录存放在 WEB-INF 目录下的 static 文件夹内,但是在 jsp 中直接访问 /layui/ 即可。

注意:

: 如果出现下面的错误,可能是没有配置<mvc:annotation-driven />的原因。

报错 > WARNING: No mapping found for HTTP request with URI ??? in DispatcherServlet with name ‘SpringMVC’

原理:

: 使用<mvc:resources />元素, 把 mapping 的 URI 注册到 SimpleUrlHandlerMapping 的 urlMap 中,key 为 mapping 的 URI pattern 值, 而 value 为 ResourceHttpRequestHandler, 这样就巧妙的把对静态资源的访问由 HandlerMapping 转到 ResourceHttpRequestHandler 处理并返回, 所以就支持 classpath 目录, jar 包内静态资源的访问. 另外需要注意的一点是, 不要对 SimpleUrlHandlerMapping 设置 defaultHandler. 因为对 static uri 的 defaultHandler 就是 ResourceHttpRequestHandler, 否则无法处理 static resources request.

提示:

: 配置的 location 一般是指向 webapp 根目录下,如果你将资源目录,放置到 webapp/WEB-INF 下面的话,那么实际路径也要相应地加上 WEB-INF。 使用这个资源映射的好处在于:访问地址可以缩减 ( 隐藏),jsp 中的http://localhost:8080/OnlineTickets/layui/css/layui.css即可访问到http://localhost:8080/OnlineTickets/WEB-INF/static/layui/css/layui.css。( 即使静态资源放在安全目录下,访问的时候,也没有/WEB-INF/static,发现了吗?)。 如下图:

imagepng

imagepng

imagepng

WEB-INF 目录作用:

: WEB-INF 是 Java 的 WEB 应用的安全目录。所谓安全就是客户端无法访问,只有服务端可以访问的目录。 如果想在页面中直接访问其中的文件,一般要通过 web.xml 文件对要访问的文件进行相应映射才能访问。现在使用<mvc:resources />,配合加上 WEB-INF 的 location,也可以达到访问的目的。

解决办法三:使用 mvc:default-servlet-handler

<mvc:default-servlet-handler/>会把 /** url, 注册到 SimpleUrlHandlerMapping 的 urlMap 中, 把对静态资源的访问由 HandlerMapping 转到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 处理并返回。 DefaultServletHttpRequestHandler 使用就是各个 Servlet 容器自己的默认 Servlet.

补充说明,多个 HandlerMapping 的执行顺序问题:

: - DefaultAnnotationHandlerMapping 的 order 属性值是:0

spring 会先执行 order 值比较小的。当访问一个 a.jpg 图片文件时,先通过 DefaultAnnotationHandlerMapping 来找处理器,一定是找不到的,我们没有叫 a.jpg 的 Action。再按 order 值升序找,由于最后一个 SimpleUrlHandlerMapping 是匹配 “/**” 的,所以一定会匹配上,再响应图片。

最后再说明一下,如何你的 DispatcherServlet 拦截 *.action 这样的 URL,静态资源不会被拦截,自然也不存在这些问题了。

文章内容整理自“# SpringMVC 访问静态资源的三种方式”,有所删改,转载请注明出处。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:PipeSoloSymWide 等,欢迎大家加入,贡献开源。

    2224 引用 • 3680 回帖 • 615 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    549 引用 • 1163 回帖 • 905 关注
感谢    关注    收藏    赞同    反对    举报    分享
回帖    
请输入回帖内容...