SpringMVC使用时没有配置<mvc:default-servlet-handler>导致的问题

出现这个问题真的是太菜了,在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/applicationContext-*.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>

十分常规配置,大多数应该都是这样配置的,至于/和/*的区别,不配置成/*主要是为了让tomcat内部对于jsp的处理生效。

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

可以看到tomcat内部配置了针对于.jsp请求处理的servlet,由于.jsp是属于后缀匹配,/*是属于路径匹配,/是属于缺省匹配。

路径匹配的优先级高于后缀匹配,所以配置成/*时SpringMVC会连.jsp请求一起处理了,但是springMVC并没有处理jsp的能力,最终就导致出现了错误。

 

问题来了

因为/是缺省匹配,所以我们配置SpringMVC是使用的缺省匹配模式,我们知道tomcat中存在一个defalutServlet,其也是缺省匹配。

我曾经以为,两个servlet的url相同的时候,他们两个是共存的,但是事实证明,如果我们把SpringMVC的url-pattern配置为了缺省匹配,默认的servlet就不能处理请求了,这个看源码应该能看出来,有兴趣的可以去看看。

所以,这时候tomcat默认的servlet是不生效的,导致对于一些.html的请求不能被处理,首先SpringMVC我们不配置资源路径的情况下其是肯定不能处理这样的请求的,tomcat默认的servlet具有处理.html请求的能力。

而<mvc:default-servlet-handler/>这个注解其作用就是使默认的servlet生效,当springMVC有处理不了的请求的时候,就会交给默认的servlet去进行处理。

这个标签干了什么?为啥配置上他就行了

 发现配置上了之后,我们的springMVC中的handlerMappings会有一个上面图示的SimpleUrlHandlerMapping,也就是多了一个根据简单的url映射的handler的简单映射,可以看出映射的url:/**,那就是所有的路径都能映射上了。那我们再来看看他映射的handler是个什么神秘人物,上面可以看到类名为DefaultServletHttpRequestHandler。

public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Assert.state(this.servletContext != null, "No ServletContext set");
    RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName);
    if (rd == null) {
        throw new IllegalStateException("A RequestDispatcher could not be located for the default servlet '" + this.defaultServletName + "'");
    } else {
        rd.forward(request, response);
    }
}

可以看出,直接就forward到了我们默认的servlet上了

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值