tomcat关于配置servlet的url-pattern的问题思路详解

tomcat在配置web.xml的时候,servlet是一个比较重要的问题,在这里讨论一下servlet中的几个痛点

  1. servlet url-pattern的匹配问题
  2. url-pattern中 //* 的区别
  3. url-pattern的优先级问题
  4. 根路径 / 的匹配问题

1 servlet url-pattern 的匹配问题

url-pattern 有三种匹配模式,分别是路径匹配、精确匹配、后缀匹配

1.1 精确匹配

<url-pattern> 中配置的项必须与url完全精确匹配。

代码举例:point_down:

<servlet-mapping>
 <servlet-name>MyServlet</servlet-name>
 <url-pattern>/kata/detail.html</url-pattern>
 <url-pattern>/demo.html</url-pattern>
 <url-pattern>/table</url-pattern>
</servlet-mapping>

当在浏览器中输入如下几种url时,都会被匹配到该servlet

http://10.43.11.143/myapp/kata/detail.html
http://10.43.11.143/myapp/demo.html

http://10.43.11.143/myapp/table

注意:

http://10.43.11.143/myapp/table/ 是非法的url,不会被当作 http://10.43.11.143/myapp/table 识别

另外上述url后面可以跟任意的查询条件,都会被匹配,如

http://10.43.11.143/myapp/table?hello 这个请求就会被匹配到MyServlet。

1.2 路径匹配

以“/”字符开头,并以“/*”结尾的字符串用于路径匹配

代码举例:point_down:

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

路径以/user/开始,后面的路径可以任意。比如下面的url都会被匹配。

http://localhost:8080/appDemo/user/users.html

http://localhost:8080/appDemo/user/addUser.action

http://localhost:8080/appDemo/user/updateUser.actionl

1.3 后缀匹配

以“*.”开头的字符串被用于后缀匹配

代码举例:point_down:

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

则任何扩展名为jsp或action的url请求都会匹配,比如下面的url都会被匹配

http://localhost:8080/appDemo/user/users.jsp

http://localhost:8080/appDemo/toHome.action

注意:路径和后缀匹配无法同时设置

注意:路径和扩展名匹配无法同时设置,比如下面的三个 都是非法的,如果设置,启动tomcat服务器会报错。

<url-pattern>/kata/*.jsp</url-pattern>

<url-pattern>/*.jsp</url-pattern>

<url-pattern>he*.jsp</url-pattern>

几个实例:point_down:,不明白请看本文第三章

2 url-pattern中 //* 的区别

<url-pattern>/</url-pattern>

<url-pattern>/*</url-pattern>

先说 /*/* 相对来讲比较好理解,它是路径匹配的一种,从范围上来讲,它是范围最广的路径匹配,所有的请求都符合它的要求,从精度上来讲,它是精度最低的路径匹配( 注意!我说的是路径匹配 ),路径匹配的优先级是从长到短的( 具体请看本文第三章 ),所以说它是精度最低的路径匹配。很多博客中说它的特点是匹配 *.jsp ,这不是废话吗? /* 本身就是路径匹配,它当然可以匹配 *.jsp

再说 / , / 是匹配优先级最低的匹配 ,当一个url和所有的 url-pattern 匹配都不合适的时候,这个url就会走 / 匹配,根本就没有什么 *.jsp 的限制,大家之所以产生了(客观上也确实是这样) / 不会匹配 *.jsp 但是 /* 会匹配 *.jsp 的原因是在tomcat/conf/web.xml里面单独配置了 *.jsp 的配置, 具体请看本文第三章

3 url-pattern的优先级问题

当一个url与多个servlet的匹配规则可以匹配时,则按照 “ 精确路径 > 最长路径>后缀匹配”这样的优先级匹配到对应的servlet。

例1:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,不会去管servletB。

例2:比如servletA的url-pattern为/test/ ,而servletB的url-pattern为/test/a/ ,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。

例3: 比如servletA的url-pattern:*.action ,servletB的url-pattern为 / * ,这个时候,如果我访问的url为http://localhost/test.action,这个时候容器就会优先进行路径匹配,而不是去匹配扩展名,这样就去调用servletB。

那么就产生了一个疑问。为什么 /* 会匹配到 *.jsp ,但是/匹配不到 *.jsp

原因很简单,在tomcat/conf/web.xml里面会有如下配置

<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>

:point_up_2:可以清楚地看到 *.jsp 作为名为jsp的servlet的后缀匹配,/*是路径匹配,其优先级高于后缀匹配,所以能匹配到后缀为jsp的文件。而 / 是级别最低的匹配,其级别低于后缀匹配,所以jsp文件不会被 url-pattern 为/的匹配到。

4 根路径 / 的匹配问题

大家应该会注意到一个问题,就是当url-pattern为/*的时候访问http://localhost:8080/会404,但是访问http://localhost:8080/index.html却没有问题(当然前提是在spring容器里面配置了 <mvc:default-servlet-handler/> )。当url-pattern为/时, http://localhost:8080/ 会自动转发到 http://localhost:8080/index.html 而不会404。原因是什么呢?

首先,我们必须要明确,一个网址的根目录即/(比如http://localhost:8080/)到底意味着什么?经过实验发现/是很特殊的,它会被url-pattern为/*的匹配,但他不会被url-pattern为/匹配。

在tomcat中,/默认是属于会被defaultservlet匹配,但是其优先级低于路径匹配,所以当某一个servlet的url-pattern为/*时,/就会被这个servlet匹配,从而不被defaultservlet匹配。

在tomcat源代码中找到如下片段可以佐证我的看法:point_down:

<!-- ==================== Default Welcome File List ===================== -->
<!-- When a request URI refers to a directory, the default servlet looks  -->
<!-- for a "welcome file" within that directory and, if present, to the   -->
<!-- corresponding resource URI for display.                              -->
<!-- If no welcome files are present, the default servlet either serves a -->
<!-- directory listing (see default servlet configuration on how to       -->
<!-- customize) or returns a 404 status, depending on the value of the    -->
<!-- listings setting.                                                    -->
<!--                                                                      -->
<!-- If you define welcome files in your own application's web.xml        -->
<!-- deployment descriptor, that list *replaces* the list configured      -->
<!-- here, so be sure to include any of the default values that you wish  -->
<!-- to use within your application.

:point_up_2:上面是讲 Welcome File List 的,即 / 路径会被默认转发到 Welcome File List 中规定的网页,即初始页。我翻译一下上面的一部分,具体的可以谷歌翻译,翻译:point_right:

翻译:point_down:

当请求URI指向目录时,默认servlet在该目录中查找“欢迎文件”,如果存在,则在相应的资源URI中查找以进行显示。如果不存在欢迎文件,则默认servlet会提供目录列表(请参阅默认servlet配置中的有关如何自定义的内容)或返回404状态,具体取决于列表设置的值

/会重定向到欢迎页面的原因是 Welcome File List 的存在, Welcome File List 发挥效果的前提是/必须被defaultservlet匹配。当某一个servlet的url-pattern为/*时,/就会被这个servlet匹配,从而不被defaultservlet匹配。所以只有在自己定义的servlet的url-pattern为/时, http://localhost:8080/ 会自动转发到 http://localhost:8080/index.html 而不会404

总结

到此这篇关于tomcat关于配置servlet的url-pattern的问题详解的文章就介绍到这了,更多相关tomcat配置servlet问题内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • tomcat报错:Wrapper cannot find servlet class ...问题解决

    tomcat发布工程时,在浏览器输入正确的地址,遇到如下问题: HTTP Status 500 - javax.servlet.ServletException: Wrapper cannot find servlet class xxx or a class it depends on .... .... java.lang.ClassNotFoundException: xxx .... ... 问题分析: web.xml文件中<servle-mapping>和<servlet-cl

  • 详解如何通过tomcat的ManagerServlet远程部署项目

    介绍 之前在邮政实习时,leader让我阅读tomcat的源代码,尝试自己实现远程部署项目的功能,于是便有了这此实践. 在Tomact中有一个Manager应用程序,它是用来管理已经部署的web应用程序,在这个应用程序中,ManagerServlet是他的主servlet,通过它我们可以获取tomcat的部分指标,远程管理web应用程序,不过这个功能会受到web应用程序部署中安全约束的保护. 当你请求ManagerServlet时,它会检查getPathInfo()返回的值以及相关的查询参数,以

  • Tomcat报错:HTTP Status 500 (Wrapper cannot find servlet class)解决办法

    Tomcat报错:HTTP Status 500 - Wrapper cannot find servlet class HTTP Status 500 - Wrapper cannot find servlet class com.servlet.servlet.RegServlet or a class it depends on type Exception report message Wrapper cannot find servlet class com.servlet.servl

  • tomcat中Servlet对象池介绍及如何使用

    tomcat中Servlet对象池 Servlet在不实现SingleThreadModel的情况下运行时是以单个实例模式,如下图,这种情况下,Wrapper容器只会通过反射实例化一个Servlet对象,对应此Servlet的所有客户端请求都会共用此Servlet对象,而对于多个客户端请求tomcat会使用多线程处理,所以应该保证此Servlet对象的线程安全,多个线程不管执行顺序如何都能保证执行结果的正确性.例如刚做web应用开发时可能会犯的一个错误:在某个Servlet中使用成员变量累加去统

  • tomcat关于配置servlet的url-pattern的问题思路详解

    tomcat在配置web.xml的时候,servlet是一个比较重要的问题,在这里讨论一下servlet中的几个痛点 servlet url-pattern的匹配问题 url-pattern中 / 和 /* 的区别 url-pattern的优先级问题 根路径 / 的匹配问题 1 servlet url-pattern 的匹配问题 url-pattern 有三种匹配模式,分别是路径匹配.精确匹配.后缀匹配 1.1 精确匹配 <url-pattern> 中配置的项必须与url完全精确匹配. 代码举

  • Spring Boot启动过程(六)之内嵌Tomcat中StandardHost、StandardContext和StandardWrapper的启动教程详解

    StandardEngine[Tomcat].StandardHost[localhost]的启动与StandardEngine不在同一个线程中,它的start: // Start our child containers, if any Container children[] = findChildren(); List<Future<Void>> results = new ArrayList<>(); for (int i = 0; i < childre

  • java中Servlet监听器的工作原理及示例详解

    监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行. 监听器原理 监听原理 1.存在事件源 2.提供监听器 3.为事件源注册监听器 4.操作事件源,产生事件对象,将事件对象传递给监听器,并且执行监听器相应监听方法 监听器典型案例:监听window窗口的事件监听器 例如:swing开发首先制造Frame**窗体**,窗体本身也是一个显示空间,对窗体提供监听器,监听窗体方法调用或者属性改变:

  • Servlet方法生命周期及执行原理详解

    目录 快速入门 创建JavaEE项目 实现接口中的抽象方法 执行 执行原理 Servlet中的生命周期方法 1.被创建:执行init方法,只执行一次 2.提供服务:执行service方法,执行多次 3.被销毁:执行destroy方法,只执行一次 Servlet3.0 Servlet体系结构 GenericServlet HttpServlet Servlet相关配置 快速入门 创建JavaEE项目 定义一个类,实现Servlet接口 public class ServletDemo1 imple

  • 教你安装eclipse2021并配置内网maven中心仓库的图文详解

    下载Eclipse2021并运行安装包,选择Eclipse IDE for Java Developers 默认安装路径 ,点击 INSTALL进行安装 安装 中... 安装完成,点击LAUNCH启动Eclipse2021 选择默认工作空间  启 动并加载插件中... 成功启动并显示IDE界面 下面是内网Maven仓库 登陆内网仓库 并复制中心仓库地址: 添加maven路径 添加前提是你先安装好maven,这里安装的是maven 3.8.1 点击Finish完成添加 添加成功后会显示如下 添加m

  • JSP开发Servlet重写init()方法实例详解

    JSP开发Servlet重写init()方法实例详解 写一个Servlet时,有时需要我们重写该Servlet的初始化方法,然后,究竟是重写init(ServletConfig config),还是重写init(),这是个问题.要明了这一点,首先要知道Servlet的几个类和接口的联系: ServletConfig接口:其中有getServletName();getServletContext();getInitParameter(String name);getInitParameterNam

  • 详解Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载: CentOS 6.4下载地址:http://www.jb51.net/softs/78243.html Nginx下载地址:http://www.jb51.net/softs/35633.html 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.nginx作为web服务器的操作讲解.nginx作为LNM

  • Vue项目全局配置微信分享思路详解

    这个项目为移动端项目,主要用于接入公众号服务.项目采用两种登录方式,微信授权登录以及账号密码登录.对于移动端项目而言,为了便于项目扩展以及提供开发热更新速度,项目分为不同的模块,每个模块是一个单页面应用.页面分为两种,一种是需要用户登录之后才能浏览,另一种是用户无需登录即可浏览.无论哪一种,均配置微信分享. 使用的技术 1.使用vue作为框架 2.使用vux作为UI组件库 全局配置微信分享思路 1.区分一般和特殊,一般情况,全局配置默认分享文案:特殊情况分两种,一种是分享内容不需要异步获取,则在

  • 对Python正则匹配IP、Url、Mail的方法详解

    如下所示: """ Created on Thu Nov 10 14:07:36 2016 @author: qianzhewoniuqusanbu """ import re def RegularMatchIP(ip):     '''进行正则匹配ip,加re.IGNORECASE是让结果返回bool型'''     pattern=re.match(r'\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?

  • Servlet文件的上传与下载详解

    目录 文件的上传和下载 1. 文件上传细节 2. 文件上传 3. 文件下载 文件的上传和下载 1. 文件上传细节 要有一个 form 标签,method-post请求 (因为get有长度限制) form标签的属性 encType 值必须为 multipart/form-data 表示提交的数据以多端(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器 在 form 标签中使用 input type="file" 添加上传的文件 编写服务器代码 (Servlet接收

随机推荐