mvc:annotation-driven和mvc:default-servlet-handler的区别

在做项目的时候,我希望静态资源由WEB服务器默认的Servlet来处理,所以我在配置文件中添加了如下的语句:

<mvc:default-servlet-handler/>

但是我再次运行项目,并访问资源的时候,发现访问@RequestMapping("/path1/path2")都不能访问了,之前没有添加的时候是能够访问的。

解决方案是,在配置文件中再添加一句代码:

 <mvc:annotation-driven/>

这样做的原因是:

在这里插入图片描述
另解:
要说明这个问题,首先要知道一个请求是如何处理的。
1.所有的请求一定都是被Servlet处理的,springmvc也是DispatcherServlet处理的,至于Servlet怎么处理则是它自己内部的事情;
2.一个请求最多只会被一个Servlet处理,至于由哪个Servlet处理,完全由Servlet配置的url-pattern决定,匹配程度最高的Servlet将处理,其他Servlet不再有机会。匹配程度从高到低依次为:
<1> 精准匹配,优先级最高;
<2> “/∗"匹配,所有不是精准匹配的请求,都会被该Servlet处理。所以应用的web.xml中如果配置了这种类型的Servlet,tomcat是没有机会处理请求的;(如果访问a.jsp、a.action都会被这个Servlet处理而不是下面模糊匹配的Servlet处理)
<3> 模糊匹配,如∗.do、∗.jsp、∗.action等,如果没有上述两种Servlet,请求将会被这个Servlet处理;
<4>”/"匹配,优先级最低,如果没有<1>、<2>类型的Servlet,并且3类型的Servlet没有匹配到,所有的请求都会由这个Servlet处理;

能够处理请求的Servlet有哪些?

  1. 应用中web.xml中注册的Servlet;
  2. tomcat配置目录下web.xml中的两个Servlet:DefaultServlet、JspServlet
 	<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

   <servlet>
       <servlet-name>jsp</servlet-name>
       <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

    请求处理的过程
        1. 从应用的web.xml、tomcat的web.xml中找出所有能够处理该请求的Servlet;
        2. 用请求名和这些Servlet的url-pattern逐个匹配,匹配程度最高的Servlet处理该请求;
        3. Servlet处理完返回结果。

    有了以上的理论基础,就可以分析请求在springmvc中是如何处理请求的了。

DispatcherServlet的url-pattern为什么是"/“而不是”/*"?

        如果配置为"/*",应用中能够处理请求的Servlet排序如下:
            /*-----------------------DispatcherServlet
            *.jsp--------------------org.apache.jasper.servlet.JspServlet
            /------------------------org.apache.catalina.servlets.DefaultServlet
      所有请求都会被DispatcherServlet处理,包括静态的xx.html、xx.js和xx.jsp。
      而我们是不会配置@RequestMapping("/xx.jsp")、	@RequestMapping("/xxhtml")这种映射的,
      除了@RequestMapping映射的请求,其他如静态请求xx.html、xx.js、xx.jsp请求就不能成功响应。
            
        
      如果配置为"/",应用中能够处理请求的Servlet排序如下:
            *.jsp--------------------org.apache.jasper.servlet.JspServlet(如果是jsp优先处理)
            /------------------------DispatcherServlet(处理剩余所有请求,包括@RequestMapping映射的请求、静态资源请求)
            /------------------------org.apache.catalina.servlets.DefaultServlet
  	    按照上述Servlet能够处理的请求类型,可以把springmvc的请求分类:JSP请求、@RequestMapping映射的请求、其他请求(html、js、png等静态请求);
        1. 如果是JSP请求,由于JspServlet的匹配程度最高,这种请求由tomcat处理;
        2. 如果是@RequestMapping映射的请求,由DispatcherServlet处理;
        3. 如果是其他请求,由DispatcherServlet处理,由于没有配置请求映射,所以无法处理
        (@RequestMapping对应的处理函数内部跳转到静态资源不算,这属于Servlet的内部逻辑);
    
    也就是说,如果DispatcherServlet的url-pattern配置成"/",默认情况下springmvc是没有处理静态资源请求能力的。
    这时就需要用到<mvc:default-servlet-handler/>,  也就引出了<mvc:default-servlet-handler/><mvc:annotation-driven />两个配置。
    无论有没有这两个配置,JSP请求都是由tomcat处理的,没有问题。
    其他请求都是由DispatcherServlet处理的,问题点在于有没有组件可以处理@RequestMapping映射的请求和静态资源请求。
        
        1 两个都没配置的时候,DispatcherServlet中的组件情况如下:
            HandlerMapping:BeanNameUrlHandlerMapping、RequestMappingHandlerMapping;
            HandlerAdapter:HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter;
            
            @RequestMapping映射的请求可以由RequestMappingHandlerMapping、RequestMappingHandlerAdapter两个组件处理;
            静态资源请求没有组件可以处理,所以无法处理;
       
        2 只配置<mvc:annotation-driven />,DispatcherServlet中的组件情况如下;
            BeanNameUrlHandlerMapping、RequestMappingHandlerMapping;
            RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter;
            
            和没有配置的时候一致,@RequestMapping映射的请求可以处理,静态资源请求无法处理;

        3 只配置<mvc:default-servlet-handler/>,DispatcherServlet中的组件情况如下;
            BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping;
            HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter;

            SimpleUrlHandlerMapping、SimpleControllerHandlerAdapter配合使用的效果就是调用tomcat的DefaultServlet处理请求,
            相当于DispatcherServlet把请求转给了tomcat的DefaultServlet处理,DefaultServlet能够处理静态资源请求,当然它肯定不知道
            DispatcherServlet中映射的请求,所以:
                静态资源请求可以处理;
                @RequestMapping映射的请求无法处理;
               
            
        4 两个配置都引入,DispatcherServlet中的组件情况如下;
            BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、SimpleUrlHandlerMapping
            RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter
            
                这就不用多说了,两对CP都在,分工明确,静态资源请求、@RequestMapping映射的请求都能处理。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我想毕业‍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值