第十章: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 />
location:指location指定的目录不要拦截,直接请求
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'

<mvc:annotation-driven />

该配置作用是注册RequestMappingHandlerMappingRequestMappingHandlerAdapter两个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 是匹配 "/**" 的,所以一定会匹配上,再响应图片。

posted @ 2020-10-12 22:48  违和感  阅读(530)  评论(0)    收藏  举报