配置DispatcherServlet应该写/仍是/*

相亲怎么作  

  web应用须要放在Tomcat容器中才能启动,Tomcat容器内有一个默认的web.xml文件,在本身项目中配置的XML文件都是继承自Tomcat中的全局XML文件并重写其中相应配置,这种继承且重写的关系和子类继承父类并重写相关方法同样,若是子类重写了父类的方法,那么就使用子类的方法,反之就使用父类的方法。像XML这种格式化的文件最终会被转换成一个类去保存配置信息,因此理解全局XML文件和项目XML文件的关系也能够类比子类重写父类方法的模式。html

  打开Tomcat安装目录下的XML文件,关注其中两个servlet及其对应的servlet-mapping。web

  • default。default servlet用于处理静态资源,若是一个请求在没法找到servlet-mapping去处理那么最终会被default处理。
  • jsp。用于处理全部jsp结尾的请求。
<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <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>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

   若是把DispatcherServlet的url-pattern配置成/*,那么它会覆盖掉jsp servlet,全部的jsp请求最交给DispatchServlet处理,若是Controller中没有配置相关处理方法那么会没法处理。事实上没有必要越俎代庖的处理.jsp请求,彻底能够交给Tomcat容器处理jsp请求,所以DispatchServlet要配置成/。spring

  看培训班的视频或者早期的SpringMVC资料,他们把DispatchServlet配置成.do或者.action形式,那是由于早期的SpringMVC缺少对静态资源的管理,若是配置成/那么全部对静态资源如js的请求也会交给DIspatchServlet处理,除非配置相应的Controller不然也会报错,全部静态资源管理的任务仍是应该由Tomcat中的default来管理,所以早期DispatchServlet配置成.do .action等形式来避免覆盖掉default的功能。apache

  这种url风格是不符合REST的要求的,因此后来SpringMVC加入了两个重要的注解,它们结合使用产生的功效是若是DispatchServlet发现请求是一个静态资源那么会交给default servlet即交给Toncat处理,效果拔群。mvc

<mvc:default-servlet-handler/>
    <mvc:annotation-driven></mvc:annotation-driven>

  总之最后的结论是:app

  • 配成/
  • springMVC里加两个注解

  如此配置以后,妈妈不再用担忧静态资源和jsp页面的问题了webapp

为何 

  为何加上了上述两个注解静态资源访问就没有问题了呢?打上断点来查看加注解先后的区别。jsp

  首先是两个注解都不加,此时HandlerMappings中的AnnotationHandlerMapping中存储这Controller和url的映射关系,因为咱们没有编写Controller去处理js html等静态资源,因此此时的状态是动态资源能够访问,静态资源不可访问。url

  

  其次是只加上default-servlet-handler,发现处理Controller的AnnotationHandler不见了,取而代之的是SimpleURLHandlerMapping,该Handler种的handlerMap很是简单只有一个/**即不管什么请求都直接去当前webapp下去找。这样配置静态资源确定是能够访问的,由于它的做用和不使用SpringMVC中的DIsplacedServlet直接使用Tomcat同样。但因为AnnotationHandler的缺失,致使Controller这种基于注解配置处理请求的方法没法访问,因此这种配置下的状态是静态资源能够访问,动态资源不能够访问。spa

  最后当把两个注解都加上的时候,不只有处理静态资源的SimpleUrlHandlerMapping,还多了一个优先级最高的RequestMapping,点开详情信息发现咱们配置的Controller都在里面。这就是咱们要的效果:对于每个非jsp请求都会被DispatchServlet拦下,而后交给优先级最高的RequestMapping处理。RequestMapping遍历本身的Mappings,若是这个请求是一个动态请求,那么必定能够找到对应的Controller,Controller处理并返回;若是该请求是一个针对静态资源文件的,RequestMapping无能为力,他会按照优先级交给后续HandlerMapping如没啥用的BeanNameUrlHandlerMapping,以及放在最后用来兜底的SimpleUrlHandlerMapping,当SimpleUrlHandlerMapping拿到一个针对静态资源的请求后,会在/**目录下找到静态资源并返回。

 

相关文章
相关标签/搜索