第十章:Spring MVC的配置访问静态资源
Spring MVC的配置访问静态资源的三种方案
访问静态资源出现问题(找不到静态文件报404)的原因:
在web.xml中配置DispatcherServlet是将url-pattern配置了【/】,该配置拦截了所有的请求,同时对*.js,*.jpg的访问也就被拦截了。
但是在Controller中又找不到相对应的静态资源处理器,所以出错。
如果你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题。
问题原因:罪魁祸首是web.xml下对spring的DispatcherServlet请求url映射的配置,原配置如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 <servlet> 7 <servlet-name>dispatcher</servlet-name> 8 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 9 <init-param> 10 <param-name>contextConfigLocation</param-name> 11 <param-value>classpath:dispatcher-servlet.xml</param-value> 12 </init-param> 13 <load-on-startup>1</load-on-startup> 14 </servlet> 15 <servlet-mapping> 16 <servlet-name>dispatcher</servlet-name> 17 <url-pattern>/</url-pattern> 18 </servlet-mapping> 19 </web-app>
下面是查询到的三种解决方案:
方案一:激活Tomcat的defaultServlet来处理静态文件
因为在tomcat的web.xml中有下面的代码:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 5 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 6 version="3.1"> 7 8 <servlet> 9 <servlet-name>default</servlet-name> 10 <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> 11 <init-param> 12 <param-name>debug</param-name> 13 <param-value>0</param-value> 14 </init-param> 15 <init-param> 16 <param-name>listings</param-name> 17 <param-value>false</param-value> 18 </init-param> 19 <load-on-startup>1</load-on-startup> 20 </servlet> 21 22 <servlet> 23 <servlet-name>jsp</servlet-name> 24 <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> 25 <init-param> 26 <param-name>fork</param-name> 27 <param-value>false</param-value> 28 </init-param> 29 <init-param> 30 <param-name>xpoweredBy</param-name> 31 <param-value>false</param-value> 32 </init-param> 33 <load-on-startup>3</load-on-startup> 34 </servlet> 35 36 <!-- The mapping for the default servlet --> 37 <servlet-mapping> 38 <servlet-name>default</servlet-name> 39 <url-pattern>/</url-pattern> 40 </servlet-mapping> 41 42 <!-- The mappings for the JSP servlet --> 43 <servlet-mapping> 44 <servlet-name>jsp</servlet-name> 45 <url-pattern>*.jsp</url-pattern> 46 <url-pattern>*.jspx</url-pattern> 47 </servlet-mapping> 48 </web-app>
所以我们可以在web.xml中配置如下:要写在DispatcherServlet的前面, 让defaultServlet先拦截,这个就不会进入dispatcher了,我想性能是最好的吧。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 <!--处理静态资源的第一种方法: 7 激活Tomcat的defaultServlet来处理静态文件 8 --> 9 <servlet-mapping> 10 <servlet-name>default</servlet-name> 11 <url-pattern>*.jpg</url-pattern> 12 </servlet-mapping> 13 <servlet-mapping> 14 <servlet-name>default</servlet-name> 15 <url-pattern>*.js</url-pattern> 16 </servlet-mapping> 17 <servlet-mapping> 18 <servlet-name>default</servlet-name> 19 <url-pattern>*.css</url-pattern> 20 </servlet-mapping> 21 22 <servlet> 23 <servlet-name>dispatcher</servlet-name> 24 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 25 <init-param> 26 <param-name>contextConfigLocation</param-name> 27 <param-value>classpath:dispatcher-servlet.xml</param-value> 28 </init-param> 29 <load-on-startup>1</load-on-startup> 30 </servlet> 31 <servlet-mapping> 32 <servlet-name>dispatcher</servlet-name> 33 <url-pattern>/</url-pattern> 34 </servlet-mapping> 35 </web-app>
补充:默认 Servlet的名字
Tomcat, Jetty, JBoss, and GlassFish 默认 Servlet的名字 -- "default"
Google App Engine 默认 Servlet的名字 -- "_ah_default"
Resin 默认 Servlet的名字 -- "resin-file"
WebLogic 默认 Servlet的名字 -- "FileServlet"
WebSphere 默认 Servlet的名字 -- "SimpleFileServlet"
方案二: 在spring3.0.4以后版本提供了mvc:resources
mvc:resources 的使用方法:<mvc:resources mapping="" location="" />+<mvc:annotation-driven>
1 <!-- 静态资源映射 --> 2 <mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/> 3 4 <mvc:annotation-driven />
mapping:指在static目录下的所有文件(**代表所有文件)
cache-period:设置静态资源在客户端浏览器中的缓存有效时间
该配置意思就是在根目录下static的所有文件不会被
DispatcherServlet拦截,直接访问,当做静态资源交给Servlet处理如果出现下面的错误,可能是没有配置<mvc:annotation-driven />的原因。
页面报404
控制台:报错WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name 'springMVC'
该配置作用是注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的,
并且提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持读写XML的支持(JAXB)和读写JSON的支持(默认Jackson)等功能
方案三 ,使用<mvc:default-servlet-handler/>+<mvc:annotation-driven>
<mvc:default-servlet-handler/>会把 "/**" url,注册到 SimpleUrlHandlerMapping 的 urlMap 中,
把对静态资源的访问由 HandlerMapping 转到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 处理并返回.
DefaultServletHttpRequestHandler 使用就是各个 Servlet 容器自己的默认 Servlet.
补充说明:多个HandlerMapping的执行顺序问题:
DefaultAnnotationHandlerMapping 的 order 属性值是:0
<mvc:resources/ >自动注册的 SimpleUrlHandlerMapping 的 order 属性值是: 2147483646
<mvc:default-servlet-handler/>自动注册的 SimpleUrlHandlerMapping 的 order 属性值是:2147483647
spring 会先执行 order 值比较小的。当访问一个 a.jpg 图片文件时,先通过 DefaultAnnotationHandlerMapping 来找处理器,一定是找不到的,我们没有叫 a.jpg 的 Action。
再按 order 值升序找,由于最后一个 SimpleUrlHandlerMapping 是匹配 "/**" 的,所以一定会匹配上,再响应图片。

浙公网安备 33010602011771号