<mvc:default-servlet-handler>与DispatcherServlet与<mvc:annotation-driven>三者关系

<mvc:default-servlet-handler>与DispatcherServlet与<mvc:annotation-driven>三者关系,第1张

"mvc:default-servlet-handler/"处理.css.js等静态资源。 遭遇情况一:明明引入静态资源路径对的一批。但是浏览器解析的时候,就是一直404.

我们在使用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等的请求。

如何解决情况一:普通请求和.css等请求的冲突?

对于这个问题 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的作用,可以在解析源码的时候了解,你就会更加明白为何限制他们的执行顺序。)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1324605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存