Spring MVC Restful构建中静态资源访问问题

在构建Spring MVC Restful风格的应用时,由于在web.xml中:

<span style="font-family:Microsoft YaHei;font-size:18px;"><servlet>
	<servlet-name>story</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>story</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping></span>

拦截了所有的请求,当然也包括对静态资源的请求拦截,如页面对image,css,js文件的引用,但是并没有定义相应的Controller来对这些请求进行响应,因此这些请求通常是无法完成的。

说到这里,我们应该想一个问题:Tomcat中,只有servlet能够处理请求,即使是jsp,也会被编译成 servlet。请注意,servlet容器中,由servlet处理这些资源那是一定了。不过,不同的 servlet 容器/应用服务器,处理这些静态资源的 servlet 的名字不大一样:

Tomcat, Jetty, JBoss, and GlassFish:默认 Servlet 名字为 "default";

Google App Engine:默认 Servlet 名字为 "_ah_default";

Resin:默认 Servlet 名字为 "resin-file";

WebLogic:默认 Servlet 名字为 "FileServlet";

WebSphere:默认 Servlet 名字为 "SimpleFileServlet";

解决以上问题常用的解决方案有以下几种:

方案一:激活 Tomcat 的 defaultServlet 来处理静态资源

<span style="font-family:Microsoft YaHei;font-size:18px;"><servlet-mapping>
	<servlet-name>default</servlet-name>
	<url-pattern>*.css</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>*.jpg</url-pattern>
</servlet-mapping></span>

每种类型的静态资源需要分别配置一个servlet-mapping,同时,要写在 DispatcherServlet 的前面, 让defaultServlet先拦截。(是不是一定要放在DispatcherServlet 前,需要您验证)

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

方案二:Spring 3.0.4 以后版本提供了<mvc:resources/>

<!-- 处理静态资源 -->

<span style="font-family:Microsoft YaHei;font-size:18px;"><!-- 上传的图片缓存1个月,其他js,css,img资源缓存一年 -->
<mvc:resources mapping="/res/**" location="/res/" cache-period="2592000"/>
<mvc:resources mapping="/css/**" location="/css/" cache-period="31536000"/>
<mvc:resources mapping="/js/**" location="/js/" cache-period="31536000"/>
<mvc:resources mapping="/img/**" location="/img/" cache-period="31536000"/></span>

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

使用 <mvc:resources /> 元素,会把 mapping 的 URI 注册到 SimpleUrlHandlerMapping 的 urlMap 中,key 为 mapping 的 URI pattern 值,而 value 为 ResourceHttpRequestHandler,这样就巧妙的把对静态资源的访问由 HandlerMapping 转到 ResourceHttpRequestHandler
处理并返回,所以就支持 classpath 目录, jar 包内静态资源的访问。

方案三:使用<mvc:default-servlet-handler/>

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

补充说明下以上提到的HandlerMapping的order的默认值:

DefaultAnnotationHandlerMapping:0

<mvc:resources/> 自动注册的SimpleUrlHandlerMapping:2147483646

<mvc:default-servlet-handler/> 自动注册的 SimpleUrlHandlerMapping:2147483647

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

Spring MVC 中,访问一个图片,还要走层层匹配。性能肯定好不到哪里去。不仅仅是 Spring MVC,即便 Struts,它们毕竟存活于servlet 容器,只要由servlet容器处理这些静态资源,必然要将这些资源读入JVM 的内存区中。所以,处理静态资源,我们通常会在前端加 apache 或 nginx。

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

一般情况下,如果我们使用Spring MVC来开发我们的应用的话,常用方案二来解决问题,也常使用<c:url value=""/>来引用一些资源,但对于像在css中引用的资源由于没有contextPath还是无法请求到,如body{background-image:url(../image/bg.jpg)},这时可以结合方案一,在web.xml中加入:

<span style="font-family:Microsoft YaHei;font-size:18px;"><servlet-mapping>
	<servlet-name>default</servlet-name>
	<url-pattern>*.jpg</url-pattern>
</servlet-mapping></span>

备注:<c:url>标签作用是将一个URL地址格式化为一个字符串,并且保存在一个变量当中。它具有URL自动重写功能。value指定的URL可以是当前工程的一个URL地址,也可以是其他web工程的URL。但是这时需要context属性。也可以添加需要传递的参数。

属性:

var :变量名称;

value:要格式化的URL;

scope:作用域范围,默认为page;

context:其他工程路径;

<c:url var="urlStr" value="/user.jsp" >
<c:param name="id" value="111" />
</c:url>
<c:url var="urlStr" value="/user.jsp" context="/project" /><!--同一容器的其他web应用-->
<c:out value="${urlStr}" />
<a href="${urlStr}"" >测试</a>

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 07-22

Spring MVC Restful构建中静态资源访问问题的相关文章

Spring mvc应用 加载静态资源的几种方式

总结几种Spring mvc应用加载静态资源的方式 1.使用服务器的默认Servlet处理 对于不同的服务器,处理静态资源的servlet-name不一样,需要去看服务器具体的配置文件 比如resin-3.1.12,通过查看app-default.xml可以看到默认处理jsp的servlet-name为>resin-jsp 所以可以通过在web.xml中添加静态资源的访问 <servlet-mapping>        <servlet-name>resin-jsp<

Spring MVC RESTful风格URL welcome-file-list不起作用问题解决

[Spring框架]<mvc:default-servlet-handler/>的作用 优雅REST风格的资源URL不希望带 .html 或 .do 等后缀.由于早期的Spring MVC不能很好地处理静态资源,所以在web.xml中配置DispatcherServlet的请求映射,往往使用 *.do . *.xhtml等方式.这就决定了请求URL必须是一个带后缀的URL,而无法采用真正的REST风格的URL. 如果将DispatcherServlet请求映射配置为"/",

EasyUI + SpringMVC 解决静态资源访问

我们的项目用的是EasyUI+SpringMVC+EJB+JPA,分享一下项目中遇到的一些问题及其解决方法.前台用的EasyUI,页面中引入了easyUI的js与css(引入路径正确),但是无论如何都显示不出来,如下图: EasyUI的样式没有,看控制台:警告,找不到 21:26:25,643 WARN [org.springframework.web.servlet.PageNotFound](http-localhost/127.0.0.1:8080-1) No mapping found

spring mvc官网下最新jar搭建框架-静态资源访问处理-注解-自动扫描

1.从官网下载spring相关jar http://spring.io/projects 点击SPRING FRAMEWORK 2.从GitHtb下载 3.向下滚动找到Downloading Artifacts 点击 4.点击Artifacts-->libs-release-local-->org-->springframewor-->spring 5.选中一个自己需要的版本(我选了4.2.5) 6.下载后的文件 配置文件的规范约束下面文件夹有的都可以写(我用到了beans, co

Spring Mvc Web 配置拦截规则与访问静态资源 (三)

拦截规则配置 1. *.do <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name

使用Spring MVC 4构建Restful服务

使用Spring MVC 4构建RESTful服务相对于其它框架来说,有很多优势.首先,Spring MVC 4作为Spring的框架之一,可以很好地与Spring进行集成.其次,Spring MVC 4的拦截器是在方法层级上的拦截,相对于其它MVC框架(如Struts2)的拦截器具有更高的效率.再者,Spring MVC 4采用基于注解的配置,入手容易,开发灵活. Spring MVC 4采用的是jacson解析JSON.jacson一款非常高效强大的JSON工具类,可以轻松地在JAVA对象与

SpringMVC REST 风格静态资源访问配置

1 在web.xml中使用默认servlet处理静态资源,缺点是如果静态资源过多,则配置量会比较大,一旦有遗漏,则会造成资源无法正常显示或404错误. <!-- 静态资源访问控制 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-

SpringBoot静态资源访问+拦截器+Thymeleaf模板引擎实现简单登陆

在此记录一下这十几天的学习情况,卡在模板引擎这里已经是四天了. 对Springboot的配置有一个比较深刻的认识,在此和大家分享一下初学者入门Spring Boot的注意事项,如果是初学SpringBoot,或者有意向学习Springboot的朋友,这篇文章可以简单的来帮助你,处理一些不必要的麻烦. 开发环境: IDea JDK1.8 SpringBoot2+ Maven3.5 1.配置Maven 首先我们打开IdeA我们从新建一个项目开始.SpringBoot是基于Maven来管理Jar包的.

【SpringMVC】静态资源访问的问题

在项目中经常会用到一些静态的资源,而一般我们在配置SpringMVC时会让SpringMVC接管所有的请求(包括静态资源的访问), 那么我们怎样才能最简单的来配置静态资源的访问呢? 一,在web.xml中让SpringMVC接管所有请求 如图 二,在SpringMVC中配置静态资源映射路径 这句话的意思是将ccc这个文件夹的访问路径映射为javaScript 也就是说 我们在地址栏里面访问JavaScript下的某个图片,其实经过SpringMVC的处理后,访问的是ccc下的文件 例如我们要访问