- 使用SpringMVC进行开发时,往往会在web.xml对DispatcherServlet进行如下配置:
<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.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>
由于<url-pattern>/</url-pattern>
/会拦截所有的除.jsp结尾的请求,在访问静态资源时,DispatcherServlet会针对该请求寻找对应名称的控制器处理对应的请求,从而会导致因为找不到相应名称的控制器报404的错误。因此,SpringMVC提供了两种处理访问静态资源的方式。
方式1
- 在springmvc配置文件中配置<mvc:default-servlet-handler />
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
在springMVC-servlet.xml中配置后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的url进行筛查。如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续交给控制处理。一般Web应用服务器默认的Servlet名称是"default",比如tomcat的配置文件web.xml中配置了名称为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>
方式2
- 在springmvc配置文件中配置<mvc:resources mapping="/resources//"
location="/resources/"/>**
<mvc:resources mapping="/img/**" location="/WEB-INF/static/img/"/>
location属性表示/WEB-INF/static/img/目录下的所有文件;
mapping属性表示匹配以/img开头的所有请求路径,如/img/a.jpg 将会访问对应目录下的/WEB-INF/static/img/a.jpg;
首先,<mvc:resources />允许静态资源放在任何地方,如WEB-INF目录下、类路径下等。通过location属性指定静态资源的位置,由于location属性是Resources类型,因此可以使用诸如"classpath:"等的资源前缀指定资源位置。传统Web容器的静态资源只能放在Web容器的根路径下而不能放到WEB-INF目录下,但是<mvc:resources />完全打破了这个限制。
其次,<mvc:resources />依据当前著名的Page Speed、YSlow等浏览器优化原则对静态资源提供优化。你可以通过cacheSeconds属性指定静态资源在浏览器端的缓存时间,一般可将该时间设置为一年,以充分利用浏览器端的缓存。在输出静态资源时,会根据配置设置好响应报文头的Expires 和 Cache-Control值。
在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303相应状态码,提示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端,以充分节省带宽,提高程序性能。