传送门

  • idea新建maven web项目
  • 普通web项目添加servlet

环境

  • tomcat:apache-tomcat-8.5.43,tomcat官网,直接下载8.5.45
  • jdk:1.8
  • 开发工具:idea

主题:新建的web项目为什么默认访问index.jsp

  • tomcat启动时,会读取web.xml文件,项目中的web.xml以及tomcat自带的(位置:apache-tomcat-8.5.43\conf\web.xml),tomcat自带两个servlet,下面是这两个servlet的映射规则(web.xml里面写的)
<!-- The mapping for the default 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>
  • 配置自己的web.xml,依据 普通web项目添加servlet 博客中所描述的项目(后面所说的配置都是依据这个项目),为HelloServlet和HiServlet多配置几个映射,配置如下
<!-- 配置和映射Servlet -->
<servlet><!--Servlet 注册的名字--><servlet-name>helloServlet</servlet-name><!--Servlet 的全类名--><servlet-class>xin.yangshuai.servlet.HelloServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><!--需要和某一个servlet 节点的 servlet-name 字节点的文本节点一致--><servlet-name>helloServlet</servlet-name><!--映射具体的访问路径:/ 代表当前 WEB 应用的根目录--><url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping><!-- 配置和映射Servlet -->
<servlet><servlet-name>hiServlet</servlet-name><servlet-class>xin.yangshuai.servlet.HiServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/hi</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/hi/*</url-pattern>
</servlet-mapping>

一、映射规则

  • 项目启动时,存储所有的映射规则(方便理解,用基本的数据结构做解释,实际数据类型为HashMap):将servlet的url-pattern做为key,servlet-name做为value,保存到map(理解为map)中。所有的url-pattern不能重复(可以与tomcat自带的两个servlet的url-pattern重复,如果重复,会覆盖tomcat自带的servlet的映射规则),具体可以看WebXml.java类的getServletMappings方法。下面是简化数据结构后,用表格描述映射规则
key value
/hi hiServlet
/hello helloServlet
/* helloServlet
/hi/* hiServlet
.jsp jsp
.jspx jsp
/ helloServlet

二、匹配规则

  • 映射规则转化为匹配规则(方便理解,用基本的数据结构做解释,实际数据类型为Mapper.MappedWrapper数组或Mapper.MappedWrapper对象),将所有的映射规则存储到四个匹配规则中,具体可以看Mapper.java类internalMapWrapper方法。下面是简化数据结构后,用表格描述匹配规则
key value 匹配规则 对象名 对象类型
/hello helloServlet 精确匹配 exactWrappers Mapper.MappedWrapper[]
/hi hiServlet 精确匹配 exactWrappers Mapper.MappedWrapper[]
(空串) helloServlet 前缀匹配 wildcardWrappers Mapper.MappedWrapper[]
/hi hiServlet 前缀匹配 wildcardWrappers Mapper.MappedWrapper[]
jsp jsp 扩展名匹配 extensionWrappers Mapper.MappedWrapper[]
jspx jsp 扩展名匹配 extensionWrappers Mapper.MappedWrapper[]
(空串) helloServlet 默认匹配 defaultWrapper Mapper.MappedWrapper

注意:这里的对象名和对象类型都是java类中使用的,可以去看源码

  • 匹配优先级如下,排在前面的优先级高
匹配规则 对象名 对象类型 映射特征(url-pattern)
精确匹配 exactWrappers 数组 具体路径,例如:/hello
前缀匹配 wildcardWrappers 数组 以/*结尾,例如:/*,/hi/*
扩展名匹配 extensionWrappers 数组 以*.开头,例如:*.jsp,*.html
默认匹配 defaultWrapper 一个对象 /,其它匹配都无法匹配时,使用默认匹配
  • tomcat自带的web.xml配置了welcome-file-list节点,该节点的子节点即为默认访问页面(welcome-file),welcome-file配置的顺序会影响到实际的默认访问,我们可以在自己的web.xml文件中配置welcome-file-list节点以覆盖tomcat自带的,tomcat自带的web.xml中配置的welcome-file-list节点如下
<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file>
</welcome-file-list>
  • 如果是默认访问,即请求根路径(ip:port/项目名/) 时,如果我们自定义的servlet没有配置“/*”前缀匹配,那么请求路径无法依据精确匹配、前缀匹配及扩展名匹配被任何servlet匹配到,此时会增加一个资源文件(welcomeResources)匹配方式,先拼接welcome-file的值再进行如上三种匹配,具体规则如下:
    1、如果只有一个welcome-file时,直接将welcome-file的值拼接到根目录后面进行匹配
    2、如果存在多个welcome-file时,按照顺序依次尝试,如果依据精确匹配、前缀匹配方式可以找到对应的servlet或者物理真实存在该文件,则使用该welcome-file的值拼接到根目录后面进行匹配,如果不存在这样的welcome-file,则使用第一个welcome-file的值拼接到根目录后面进行匹配。
    注意:这里说的物理真实存在表示,在项目的webapp文件夹下存在这样的文件,即文件名和后缀与welcome-file的值相同

三、实例验证

仍然使用 前文提到的项目 ,servlet和项目结构都不变。项目的web.xml发生变化,覆盖tomcat自带的web.xml的welcome-file-list,现在web.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!-- tomcat自带的两个servlet,位置在tomcat根目录/conf/web.xml里面,把其中的映射粘贴过来--><!--The mapping for the default 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>--><!--tomcat自带web.xml中的欢迎页,直接粘贴过来--><!--    <welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file></welcome-file-list>--><!-- 配置helloServlet --><servlet><!--Servlet 注册的名字--><servlet-name>helloServlet</servlet-name><!--Servlet 的全类名--><servlet-class>xin.yangshuai.servlet.HelloServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><!-- 配置hiServlet --><servlet><servlet-name>hiServlet</servlet-name><servlet-class>xin.yangshuai.servlet.HiServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><!--配置welcome-file-list--><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 配置helloServlet映射 --><!-- 配置hiServlet映射 --></web-app>

  • 1、servlet配置了/*映射,则用此servlet来处理默认访问
    web.xml
<!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/index.html</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/*</url-pattern>
</servlet-mapping>

运行结果:hiServlet配置了/*映射,则由hiServlet来处理默认访问


  • 2、servlet没有配置/*映射,只有一个welcome-file时,则直接将welcome-file的值拼接到根目录后面进行匹配
    web.xml
<!--配置welcome-file-list-->
<welcome-file-list><welcome-file>index.html</welcome-file>
</welcome-file-list><!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/index.html</url-pattern>
</servlet-mapping>

运行结果:没有servlet配置/*,只有一个welcome-file,值为index.html,则默认访问相当于:http://localhost:8080/first_page/index.html,hiServlet配置的精确匹配,所有由hiServlet来处理默认访问。


  • 3、其实welcome-file不用写成一个页面的样子,可以随意的写,可以没有后缀,可以有层级。
    web.xml
<!--配置welcome-file-list-->
<welcome-file-list><welcome-file>hh/index.html</welcome-file>
</welcome-file-list><!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/hh/*</url-pattern>
</servlet-mapping>
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/hh/index.html</url-pattern>
</servlet-mapping>

运行结果::没有servlet配置/*,只有一个welcome-file,则默认访问相当于:http://localhost:8080/first_page/hh/index.html,hiServlet配置的精确匹配,所以由hiServlet来处理默认访问。
注意:没有精确匹配时,也会寻找可以进行前缀匹配、扩展名匹配的servlet进行匹配。


  • servlet没有配置/*映射,如果存在多个welcome-file时,按照顺序依次尝试,如果存在依据精确匹配、前缀匹配方式获取的servlet或者物理真实存在该文件,则使用该welcome-file的值拼接到根目录后面进行匹配,如果不存在这样的welcome-file,则使用第一个welcome-file的值拼接到根目录后面进行匹配。
    注意:存在多个welcome-file,默认请求尝试拼接welcome-file的值时,是不考虑扩展名匹配的。

  • 4、尝试拼接:依据物理真实存在文件
    web.xml
<!--配置welcome-file-list-->
<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file>
</welcome-file-list><!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>*.html</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/hi</url-pattern>
</servlet-mapping>

运行结果:没有servlet配置/*,存在多个welcome-file时,按照顺序依次尝试,首先尝试拼接index.html,但是index.html并非物理真实存在,并且不能精确匹配或者前缀匹配,所以index.html被舍弃,同样道理,index.htm也会被舍弃,然后尝试index.jsp,index.jsp物理真实存在,所以拼接index.jsp,默认访问相当于:http://localhost:8080/first_page/index.jsp,此路径可以由tomcat自带的名为jsp的servlet进行扩展名(*.jsp)匹配,这也就是我们新建项目默认访问的页面。


  • 5、我们可以覆盖默认的映射规则,比如覆盖*.jsp
    web.xml
<!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>*.jsp</url-pattern>
</servlet-mapping>

运行结果:与上面相同的分析过程相同,默认访问相当于:http://localhost:8080/first_page/index.jsp,由于hiServlet覆盖了*.jsp映射规则,所以由hiServlet处理默认访问。


  • 6、尝试拼接:依据前缀匹配
    web.xml
<!--配置welcome-file-list-->
<welcome-file-list><welcome-file>hh/index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file>
</welcome-file-list><!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>*.jsp</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/hh/*</url-pattern>
</servlet-mapping>

运行结果:没有servlet配置/*,存在多个welcome-file时,按照顺序依次尝试,首先尝试拼接hh/index.html,可以看出,hiServlet配置了/hh/*的映射规则,符合前缀匹配,所以拼接hh/index.html,默认访问相当于:http://localhost:8080/first_page/hh/index.html,所以由hiServlet处理默认访问。
注意:除了依据前缀匹配,也可以依据精确匹配。


7、尝试拼接:不能依据扩展名匹配
web.xml

<!--配置welcome-file-list-->
<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file>
</welcome-file-list><!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>*.html</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/hh</url-pattern>
</servlet-mapping>

运行结果:没有servlet配置/*,存在多个welcome-file时,按照顺序依次尝试,此时默认访问相当于:http://localhost:8080/first_page/index.jsp,依据物理真实存在文件拼接。helloServlet虽然配置了*.html后缀匹配规则,但是并没有拼接index.html。


  • 8、尝试拼接:无法依据精确匹配,前缀匹配和物理真实存在文件匹配,则使用第一个拼接。
    我们将项目的index.jsp删掉(改个名相当于删除了)

    web.xml(与上面相同)
<!--配置welcome-file-list-->
<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file>
</welcome-file-list><!-- 配置helloServlet映射 -->
<servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>*.html</url-pattern>
</servlet-mapping><!-- 配置hiServlet映射 -->
<servlet-mapping><servlet-name>hiServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

运行结果:没有servlet配置/*,存在多个welcome-file时,按照顺序依次尝试,此时依据精确匹配,前缀匹配和物理真实存在文件匹配都无法匹配到,所以拼接第一个,默认访问相当于:http://localhost:8080/first_page/index.html,此时只有helloServlet配置了*.html扩展名匹配,所以由helloServlet来处理默认访问。


总结

  • 匹配优先级
    精确匹配
    前缀匹配
    扩展名匹配
    资源文件匹配(如果是默认访问)
    默认匹配
  • 默认访问拼接原则
    如果是默认访问,即请求根路径(ip:port/项目名/) 时,如果我们自定义的servlet没有配置“/*”前缀匹配,那么请求路径无法依据精确匹配、前缀匹配及扩展名匹配被任何servlet匹配到,此时会增加一个资源文件(welcomeResources)匹配方式,先拼接welcome-file的值再进行如上三种匹配,具体规则如下:
    1、如果只有一个welcome-file时,直接将welcome-file的值拼接到根目录后面进行匹配
    2、如果存在多个welcome-file时,按照顺序依次尝试,如果依据精确匹配、前缀匹配方式可以找到对应的servlet或者物理真实存在该文件,则使用该welcome-file的值拼接到根目录后面进行匹配,如果不存在这样的welcome-file,则使用第一个welcome-file的值拼接到根目录后面进行匹配。

如有错误,欢迎指正!!!


参考:https://www.cnblogs.com/fangjian0423/p/servletContainer-tomcat-urlPattern.html

新建的web项目为什么默认访问index.jsp相关推荐

  1. 从零开始搭建python flask+vue 小型web项目以及flask_sqlalchemy访问数据库

    重零开始搭建python flask+vue 小型web项目以及flask_sqlalchemy访问数据库 前言 作者是一个前端开发者,之前从未接触过python,也没接触过后端开发,所有这篇文章中有 ...

  2. spring boot新建非web项目(无需依赖)

    spring boot新建非web项目(无需依赖) spring boot集成spring data jpa的时候需要jdk版本为1.8,所以jdk的版本最好设置为1.8 如果新建的项目是以jsp为模 ...

  3. Eclipe 新建maven web 项目

    eclipse 新建maven web项目: 1.创建web项目 空白处---右击--->New---->Other--->MavenProject--->filter web ...

  4. 使用Intellij idea新建Java Web项目(servlet) 原理及初步使用

    准备 JDK       (配置JDK_HOME\bin   和 CLASSPATH)   注:JDK8下载已经需要注册了,请使用JDK11(现在是官方长期支持的版本)     对于我们新手来说,JD ...

  5. JavaWeb开发---B/S和C/S模式 tomcat服务器 Tomcat项目部署和发布 静态网页和动态网页 tomcat对web项目的目录要求 使用idea开发工具创建web项目 设置默认首页

    目录 1. B/S和C/S模式 1.1 C/S模式 1.2 B/S模式 1.3 B/S和C/S区别 2.服务器 3.web 服务器 3.1.IIS 3.2.Tomcat 3.3.Zeus 3.4.Ng ...

  6. IntelliJ IDEA中新建JAVA WEB项目、maven项目

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 在IntelliJ IDEA 中新建一个Web应用项目. 1. 在主界面顶部菜单栏依次"F ...

  7. Eclipse中web项目的默认发布路径改为外部Tomcat中webapp路径

    可参考http://www.cnblogs.com/mihu/p/4772509.html 和http://www.cnblogs.com/dyllove98/archive/2013/06/07/3 ...

  8. idea部署web项目,能访问jsp,访问Servlet却出现404错误的解决方法汇总

    https://www.cnblogs.com/hlyxd/p/13092615.html 一.JAVA servlet 2.x规范: 项目目录结构必须要有WEB-INF,web.xml等文件夹和文件 ...

  9. java web项目为什么我们要放弃jsp?

    前戏: 以前的项目大多数都是java程序猿又当爹又当妈,又搞前端(ajax/jquery/js/html/css等等),又搞后端(java/mysql/Oracle等等). 随着时代的发展,渐渐的许多 ...

  10. springboot 设置默认访问index.html_【SpringBoot WEB系列】WebFlux静态资源配置与访问

    [SpringBoot WEB系列]WebFlux静态资源配置与访问 上一篇博文介绍SpringMVC的静态资源访问,那么在WebFlux中,静态资源的访问姿势是否一致呢 I. 默认配置 与Sprin ...

最新文章

  1. ASP中关于全局页面的作用 asax文件
  2. 在Windows2012R2中如何安装IIS8.5
  3. matlab之unwrap函数
  4. QDoc特殊内容special content
  5. vue --- 前端代理发送http请求
  6. leetcode306. 累加数(回溯)
  7. LeetCode - Easy - 118. Pascal‘s Triangle
  8. python配色_python语言再次解决文章配色难题
  9. swagger: fetching resource list: http://localhost:8080/template/v2/api-docs?group=springboot-templat
  10. 计算机组成与设计---硬件/软件接口---计算机概要与技术
  11. hadoop合并日志_hadoop 日志处理
  12. JAVA新生入学报到管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  13. 数据库常用表操作SQL语句案例
  14. GROMACS运行参数之em.mdp文件详解
  15. C++报错信息:LNK2001:无法解析的外部符号 原因分析及解决方法
  16. Spark数据分析之第5课
  17. WifiManager详解
  18. 在字节跳动干软件测试5年,4月无情被辞,想给划水的兄弟提个醒
  19. 老紫竹的南大通用面试PPT文档下载
  20. 微信公众号三方平台开发【获取授权方的授权信息以及基本信息】

热门文章

  1. 计算机毕业设计(附源码)python医院人事及科室病区管理
  2. 三星发布全球首款太阳能笔记本
  3. 学计算机专业1050显卡够不够,gtx1050显卡性能怎么样
  4. PKI/CA/电子签名等相关名词解释
  5. 优先队列式分支限界法,完成这n个任务在k个机器的最佳调度。
  6. 恒天餐饮管理系统服务器代码,恒天餐饮管理软件使用教程.doc
  7. python nlp文本摘要_NLP(十一) 提取文本摘要
  8. 从VISTA到WIN 7 揭秘全球软件开发模式的变迁
  9. 变量、函数、类等编程时常用英文命名和缩写
  10. 三星nfc添加门禁卡实测有效_今天才知道!iPhone手机还能变成门禁卡,60秒就能实现...