mvc:annotation-driven和mvc:default-servlet-handler的作用

要说明这个问题,首先要知道一个请求是如何处理的

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处理完返回结果。


1.DispatcherServlet的url-pattern为什么是 / 而不是 /*

因为tomcat的两个Servlet中

  • DefaultServlet(用来访问静态资源,例如xx.css、xx.html)的url-pattern的拦截等级最低
  • JspServlet(用来访问jsp,例如xx.jsp)的url-pattern拦截等级是模糊匹配

/*的优先级比/的高,当DispatherServlet设置为/∗后,所有的请求都只会通过DispatcherServlet来处理,包括xx.jsp、xx.html、xx.js等等,而我们是不会配置@RequestMapping("/xx.jsp")、 @RequestMapping("/xx.html")这种映射的

除了@RequestMapping映射的请求,其他如静态请求xx.html、xx.js、xx.jsp请求就不能成功响应。

解决方式
如果配置为"/",应用中能够处理请求的Servlet排序如下:

  1. *.jsp —> 通过JspServlet进行处理
  2. / —> DispatcherServlet(处理剩余所有请求,包括@RequestMapping映射的请求、静态资源请求)
  3. / —> DefaultServlet

DispatcherServlet和DefaultServlet,两者的url-pattern相同,所以后一个覆盖前一个,除了*.jsp以外的所有请求,都将被DispatcherServlet处理(不会走到DefaultServlet),而我们压根不会配置@RequestMapping("/xx.html")这种映射,所以静态资源无法请求

按照上述Servlet能够处理的请求类型,可以把springmvc的请求分类:JSP请求、@RequestMapping映射的请求、其他请求(html、js、png等静态请求);

  1. 如果是JSP请求,由于JspServlet的匹配程度最高,这种请求由tomcat处理;
  2. 如果是@RequestMapping映射的请求,由DispatcherServlet处理;
  3. 如果是其他请求,由DispatcherServlet处理,由于没有配置请求映射,所以无法处理(@RequestMapping对应的处理函数内部跳转到静态资源不算,这属于Servlet的内部逻辑);

验证:
设置DispatcherServlet的拦截路径为/

<!-- 配置SpringMVC -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/user-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

在webapp下新建两个文件,index.html和index.jsp,我们发现可以请求index.jsp但是请求index.html会报404异常
在这里插入图片描述


2.mvc:annotation-driven和mvc:default-servlet-handler的作用

也就是说,如果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中的组件情况如下;
HandlerMapping:BeanNameUrlHandlerMapping、RequestMappingHandlerMapping;
HandlerAdapter:RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter;

和没有配置的时候一致,@RequestMapping映射的请求可以处理,静态资源请求无法处理;

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

SimpleUrlHandlerMapping、SimpleControllerHandlerAdapter配合使用的效果就是调用tomcat的DefaultServlet处理请求,相当于DispatcherServlet把请求转给了tomcat的DefaultServlet处理,DefaultServlet能够处理静态资源请求,当然它肯定不知道DispatcherServlet中映射的请求,所以:静态资源请求可以处理;@RequestMapping映射的请求无法处理;

(4)两个配置都引入,DispatcherServlet中的组件情况如下;
HandlerMapping: BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、SimpleUrlHandlerMapping
HandlerAdapter:RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter

这就不用多说了,两对CP都在,分工明确,静态资源请求、@RequestMapping映射的请求都能处理。

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值