Tomcat和应用处理请求的级别和流程如下图所示:
对资源的访问地址为:http://ip:port/应用名/资源名
1:根据ip和port确定是哪个tomcat。
2:根据应用名确定是哪个应用。
3:根据资源名来确定访问哪个资源。
4:如果web.xml配置的DispatcherServlet的拦截路径是“*.do/*.action”,则springmvc不会处理静态资源的请求,静态资源的请求最终还是交由tomcat的默认Servlet来处理。(tomcat的默认Servlet的作用:首先所有的请求进入tomcat,其次进入应用,然后开始遍历应用中配置的Servlet的拦截路径,如果没有匹配到应用指定的所有servlet路径,那么就会流到默认的servlet。)
5:如果web.xml配置的DispatcherServlet的拦截路径是“/”,则springmvc也会处理对静态资源的请求,这样就会出现问题。
问题描述:
如果在配置DispatcherServlet的时候,拦截 *.do或者*.action这样的URL,由于不会拦截对*.jpg,*.css,*.js等静态资源的访问,所以静态资源的请求最终交由Tomcat的默认Servlet来处理,就不会出现访问不到静态资源的问题。但是如果在配置DispatcherServlet时拦截“/”,拦截了所有的请求,即同时拦截了对*.js,*.jpg的访问,则会出现找不到静态资源文件,报404错误。
方案一:让Tomcat的defaultServlet来处理静态文件。(在springmvc拦截到对静态资源的访问之前抢先用默认Servlet拦截到对静态资源的访问)
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</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>*.css</url-pattern>
</servlet-mapping>
要配置多个servlet-mapping,每种类型文件配置一个;要写在DispatcherServlet的前面, 让defaultServlet先拦截,这样对静态资源文件的请求就不会进入SpringMVC了。
各种web服务器默认Servlet的名字如下:
Tomcat, Jetty, JBoss, and GlassFish 默认 Servlet的名字 -- "default"
Google App Engine 默认 Servlet的名字 -- "_ah_default"
Resin 默认 Servlet的名字 -- "resin-file"
WebLogic 默认 Servlet的名字 -- "FileServlet"
默认的Servlet为什么能处理静态请求呢?
方案二: 使用<mvc:resources /> (在springmvc拦截到对静态资源的访问之后,由springmvc对静态资源特殊处理)
<mvc:resources/> 的使用方法:
<!--对静态资源文件的访问-->
<mvc:resources mapping="/images/**" location="/images/" />
在mapping属性配置页面文件中对静态资源的请求路径,在location属性配置静态资源存放的目录。
mapping属性会将符合条件的请求映射到 ResourceHttpRequestHandler 进行处理,最终从location指定的目录中找到静态资源,并向客户端做出响应。
方案三 :使用<mvc:default-servlet-handler/>(在springmvc拦截到对静态资源的访问之后,再将静态资源交由默认Servlet进行处理)
在Spring MVC 的配置文件中提供了一个<mvc:default-servlet-handler/>标签。在 WEB 容器启动的时候会在上下文中定义一个 DefaultServletHttpRequestHandler,它会对DispatcherServlet的请求进行处理(即被DispatcherServlet拦截的请求下一步会经过DefaultServletHttpRequestHandler);如果该请求已经作了映射,那么会接着交给后台对应的处理程序;如果没有作映射,就交给 WEB 应用服务器默认的 Servlet 处理(即Tomcat默认的Servlet),从而找到对应的静态资源;只有再找不到资源时才会报错。
和方案一中说的一样,某些 WEB 应用服务器默认的 Servlet的名字是 default。如果默认 Servlet 用不同名称自定义配置,或者在缺省 Servlet 名称未知的情况下使用了不同的 Servlet 容器,则必须显式提供默认 Servlet 的名称,如下:
<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>
这都是在xml中配置的情况,应该还有使用JavaConfig配置的情况,待总结……