配置DispatcherServlet应该写/还是/*
相亲怎么做
web应用需要放在Tomcat容器中才能启动,Tomcat容器内有一个默认的web.xml文件,在自己项目中配置的XML文件都是继承自Tomcat中的全局XML文件并重写其中相应配置,这种继承且重写的关系和子类继承父类并重写相关方法一样,如果子类重写了父类的方法,那么就使用子类的方法,反之就使用父类的方法。像XML这种格式化的文件最终会被转换成一个类去保存配置信息,所以理解全局XML文件和项目XML文件的关系也可以类比子类重写父类方法的模式。
打开Tomcat安装目录下的XML文件,关注其中两个servlet及其对应的servlet-mapping。
- 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要配置成/。
看培训班的视频或者早期的SpringMVC资料,他们把DispatchServlet配置成.do或者.action形式,那是因为早期的SpringMVC缺乏对静态资源的管理,如果配置成/那么所有对静态资源如js的请求也会交给DIspatchServlet处理,除非配置相应的Controller否则也会报错,所有静态资源管理的任务还是应该由Tomcat中的default来管理,因此早期DispatchServlet配置成.do .action等形式来避免覆盖掉default的功能。
这种url风格是不符合REST的要求的,所以后来SpringMVC加入了两个重要的注解,它们结合使用产生的功效是如果DispatchServlet发现请求是一个静态资源那么会交给default servlet即交给Toncat处理,效果拔群。
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
总之最后的结论是:
- 配成/
- springMVC里加两个注解
如此配置之后,妈妈再也不用担心静态资源和jsp页面的问题了
为什么
为什么加上了上述两个注解静态资源访问就没有问题了呢?打上断点来查看加注解前后的区别。
首先是两个注解都不加,此时HandlerMappings中的AnnotationHandlerMapping中存储这Controller和url的映射关系,由于我们没有编写Controller去处理js html等静态资源,所以此时的状态是动态资源可以访问,静态资源不可访问。
其次是只加上default-servlet-handler,发现处理Controller的AnnotationHandler不见了,取而代之的是SimpleURLHandlerMapping,该Handler种的handlerMap非常简单只有一个/**即无论什么请求都直接去当前webapp下去找。这样配置静态资源肯定是可以访问的,因为它的作用和不使用SpringMVC中的DIsplacedServlet直接使用Tomcat一样。但由于AnnotationHandler的缺失,导致Controller这种基于注解配置处理请求的方法无法访问,所以这种配置下的状态是静态资源可以访问,动态资源不可以访问。
最后当把两个注解都加上的时候,不仅有处理静态资源的SimpleUrlHandlerMapping,还多了一个优先级最高的RequestMapping,点开详情信息发现我们配置的Controller都在里面。这就是我们要的效果:对于每一个非jsp请求都会被DispatchServlet拦下,然后交给优先级最高的RequestMapping处理。RequestMapping遍历自己的Mappings,如果这个请求是一个动态请求,那么一定可以找到对应的Controller,Controller处理并返回;如果该请求是一个针对静态资源文件的,RequestMapping无能为力,他会按照优先级交给后续HandlerMapping如没啥用的BeanNameUrlHandlerMapping,以及放在最后用来兜底的SimpleUrlHandlerMapping,当SimpleUrlHandlerMapping拿到一个针对静态资源的请求后,会在/**目录下找到静态资源并返回。
最新文章
- 获取本机IP
- 【leetcode】Minimum Size Subarray Sum(middle)
- 实时刷新Winform中Label的Text
- eclispe使用外部tomcat总结
- Treap实现山寨set
- 在getView方法产生给用户item的视图以及数据
- Designing CSS Layouts With Flexbox Is As Easy As Pie
- 正确理解Spring AOP中的Around advice
- Java多线程之Wait()和Notify()
- iOS开发——UI篇Swift篇&;UITabBarController
- 【ZOJ】3609 Modular Inverse
- list和数组之间相互的转化
- SPI协议总结
- Tomcat学习笔记 - 错误日志 - NetBeans配置tomcat出错情况总结 -- 尚未授予访问 Tomcat 服务器的权限。请在服务器管理器的 Tomcat 定制器中设置 ";manager-script"; 角色的正确用户名和口令。 有关详细信息, 请查看服务器日志。
- 教务处sso设计缺陷
- Python自然语言处理学习笔记之选择正确的特征(错误分析 error analysis)
- 【Java 并发】详解 ThreadLocal
- Android 沉浸式状态栏攻略 让你的状态栏变色吧
- volley+okhttp封装,一行代码就可访问网络
- AngularJS 关于ng-model和ng-bind还有{{}}
热门文章
- Math.max()/min()
- linux定时任务crontab 实现如何每秒执行一次!
- react-router 嵌套路由 内层route找不到
- 洛谷P4726 【模板】多项式指数函数(多项式exp)
- Mysql sql 功能分类
- IntelliJ IDEA 编译Java程序出现 &#39;Error:java: 无效的源发行版: 9&#39; 的解决方案
- 接口自动化&#160;[授客]基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0
- Centos 7 查看内存占用情况相关命令
- L2-024. 部落
- turnserver 配置说明记录