我们在使用SSM开发的时候会经常使用下面代码引入.css,Jquery等静态资源。
${pageContext.request.contextPath}/static/css/webbase.css" type="text/css" rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="
${pageContext.request.contextPath}/static/css/pages-login-manage.css"/>
<script type="text/javascript" src="
${pageContext.request.contextPath}/static/js/jquery.min.js" rel="stylesheet"></script>
但是我们经常会遇到这样的情况:
我们在使用SSM开发的时候,都会配置一个前端控制器,DispatcheServlet
配置的拦截路径也都是“/”.
<!--配置SpringMVC的前端控制器,加载配置文件。使用扩展方式-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
它的意思就是: Spring MVC 将接收到的所有请求都看作是一个普通的请求,包括对于静态资源的请求(如.css,.js等后缀的)
这样一来,所有对于静态资源的请求都会被看作是一个普通的后台控制器请求,然后这个前端控制器就会傻乎乎的拿着类似这样的地址:http://localhost:8080/Work/static/js/jquery.min.js去Contorller寻找对应的@RequestMapping。那很明显,肯定找不到。导致请求找不到而报 404 异常错误。
那么问题就显而易见了,就是由于DispatcherServler,“太笨了”,它区分不了,普通的@requestMapping请求和静态资源.css,.js等的请求。
对于这个问题 Spring MVC 在全局配置文件中提供了一个标签。
<mvc:default-servlet-handler/>
该标签作用:在 WEB 容器启动的时候会在上下文中定义一个 DefaultServletHttpRequestHandler,它会对DispatcherServlet的请求进行处理,如果该请求已经作了映射,即存在相应的@requestMapping,那么会接着交给后台对应的处理程序,如果没有作映射,就交给 WEB 应用服务器默认的 Servlet 处理,从而找到对应的静态资源,只有再找不到资源时才会报错。(像http://localhost:8080/Work/static/js/jquery.min.js那指定不存在所以就会交给WEB应用服务器默认的Servlet处理,这个可以帮我们找到.css等静态资源)。
那么到现在为止,问题就解决了吗?
唉嘿,可以说解决一半了,因为有时候由于不知道啥问题,这个由标签mvc:default-servlet-handler/生成的默认Servelt总是在DispatcheServlet之前拦截所有请求,那就导致一种情况,原本呢,我没有配置mvc:default-servlet-handler/,那我正常的普通请求还可以响应(只是关于.css等静态资源不行)但是我加了mvc:default-servlet-handler/以后,发现连普通的都不可以了。报错就是找不到某静态资源。
这是因为这个默认的Servlert会在DispatcherServlet之前将所有的请求都拦截下,都当作静态资源去处理。那普通的路径请求,肯定不可以当作静态资源处理啊。所以就出现了找不到"某某某静态资源的错误了"。
对此,SpringMVC提供了一个标签
<mvc:annotation-driven/>
mvc:annotation-driven/的作用是自动注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter这两个bean。相当于:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
也就是说这两个bean的顺序,一定要在mvc:default-servlet-handler/的前面。mvc:default-servlet-handler/定义的DefaultServletHttpRequestHandler,是当没有其他mapping可以处理请求时才会执行该handler匹配的mapping,从而去查找静态内容,这不就完美的解决了吗?
(这两个Bean的作用,可以在解析源码的时候了解,你就会更加明白为何限制他们的执行顺序。)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)