配置web.xml中的DispatcherServlet:
1 <servlet>
2 <servlet-name>SpringMVC</servlet-name>
3 <servletclass>
4 org.springframework.web.servlet.DispatcherServlet
5 </servlet-class>
6 <load-on-startup>1</load-on-startup>
7 </servlet>
8
9 <servlet-mapping>
10 <servlet-name>SpringMVC</servlet-name>
11 <url-pattern>/</url-pattern>
12 </servlet-mapping>
通过上面url-pattern的配置,所有URL请求都将被SpringMVC的DispatcherServlet拦截(即所有请求交给SpringMVC去处理)。于是,静态资源无法正确访问。如果 DispatcherServlet拦截类似于*.do这样的URL,就不存在该问题了。
3种解决方案
方案一 激活Tomcat的defaultServlet来处理静态资源
1 <servlet-mapping>
2 <servlet-name>default</servlet-name>
3 <url-pattern>*.jpg</url-pattern>
4 </servlet-mapping>
5
6 <servlet-mapping>
7 <servlet-name>default</servlet-name>
8 <url-pattern>*.js</url-pattern>
9 </servlet-mapping>
10
11 <servlet-mapping>
12 <servlet-name>default</servlet-name>
13 <url-pattern>*.css</url-pattern>
14 </servlet-mapping>
写在SpringMVC的DispatcherServlet前面, 请求先由Tomcat的defaultServlet拦截,静态资源请求不会交给SpringMVC去处理,性能最好。
备注:
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允许静态资源放在任何地方,如WEB-INF目录下、类路径下,也可以将js等静态文件打到jar包中。
1 <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
2 <mvc:resources mapping="/resources/**" location="/resources/" />
3 <mvc:resources mapping="/images/**" location="/images/" />
4 <mvc:resources mapping="/js/**" location="/js/" />
mapping:映射。
location:本地资源路径,必须是webapp(WebContent和WebRoot也可以)根目录下的路径。
两个*表示映射所有的URL,包括子路径(即接多个/)。如果出现错误—WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name 'springMVC',可能没有配置
1 <mvc:annotation-driven />
<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。
方案三 使用<mvc:default-servlet-handler/>
如果是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理;如果不是静态资源的请求,由DispatcherServlet处理。
1 <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。
SpringMVC根据order属性值升序排列顺序依次执行多个HandlerMapping。
注意:静态资源访问路径可能会受到Controller层前缀URL的影响,需要加上一个或多个../来消除。
参考资料
SpringMVC 之<mvc:default-servlet-handler />