引入
Tomcat 在处理HTTP请求时,会根据一系列规则和配置来判断该请求是想要获取动态资源还是静态资源。
为什么要对请求进行判断?
Tomcat 判断HTTP请求是动态请求还是静态请求的主要目的是确定如何生成并返回响应内容。静态请求通常意味着服务器只需读取并返回文件系统中的某个文件,而动态请求则意味着服务器需要执行一些代码或逻辑来生成响应。
静态资源和动态资源是什么?(定义)
静态资源:
- 静态资源指的是在服务器端生成后,不会在客户端进行动态改变的资源。
- 这些资源通常包括HTML、CSS、JavaScript文件,以及图片、视频、音频等多媒体内容。
- 静态资源在请求时,服务器直接返回其内容,客户端只需进行渲染或播放。
动态资源:
- 动态资源则是指那些在程序运行时可以改变或更新的资源。
- 这些资源通常包括数据文件、网络连接、用户输入等,它们的状态可以在程序执行期间发生变化。
- 动态资源需要服务器进行实时处理,根据用户的请求和数据库中的数据生成响应的内容
那么怎么去判断呢?
引用(网络资源回答)
URL匹配:
- Tomcat 首先会根据请求的URL来尝试匹配静态资源。如果请求的URL直接对应到文件系统中的某个文件(例如
.html
、.css
、.js
等),并且该文件存在,则Tomcat 会将其视为静态请求。- 如果请求的URL不匹配任何静态资源,Tomcat 会进一步检查是否有Servlet或JSP等动态资源的映射规则与之匹配。
Servlet映射:
- Tomcat 的
web.xml
配置文件(或注解配置)中定义了Servlet的映射规则。当请求的URL与某个Servlet的映射规则匹配时,Tomcat 会将其视为动态请求,并将请求转发给相应的Servlet进行处理。- 需要注意的是,Tomcat 还提供了一个默认的Servlet(如
DefaultServlet
),它负责处理所有未明确映射到特定Servlet的静态资源请求。然而,这并不意味着所有未匹配到动态资源的请求都是静态请求,因为还可能有其他处理逻辑(如过滤器、重定向等)在起作用。请求头信息:
- 虽然Tomcat 主要通过URL和Servlet映射来判断请求类型,但请求头信息有时也可以提供有用的线索。例如,某些请求可能会包含特定的请求头(如
Accept
),表明客户端期望接收的内容类型。然而,这通常不是判断请求类型的决定性因素。文件后缀:
- 在某些情况下,Tomcat 可能会根据请求的文件后缀来判断请求类型。例如,
.jsp
后缀通常表示动态请求,而.html
、.jpg
等后缀则通常表示静态请求。然而,这种方法并不是绝对可靠的,因为文件后缀可以被更改或伪造。自定义逻辑:
- 开发者还可以通过编写自定义的过滤器、拦截器等组件来扩展Tomcat的请求处理逻辑。这些组件可以在请求到达Servlet之前对请求进行预处理和判断,从而实现对请求类型的自定义判断和处理。
上面是一些官方回答,那么究竟是怎么判断的呢?
简单而言,tomcat想要确定请求访问的是动态资源还是静态资源,先从动态资源中查找(存在动态资源映射表),若是能从中查到,则返回动态资源,若是不能从动态中匹配,那么再去静态序列查找,能查到就返回静态资源,静态也查不到就返回404。
动态资源映射表
动态资源映射表是一种数据结构或数据库表,它用于记录和管理动态资源与相应物理资源或逻辑资源之间的映射关系。在Web服务器(如Tomcat)或应用程序中,动态资源通常指的是那些需要服务器实时处理或生成的资源,如JSP页面、Servlet、数据库查询结果等。
如下的表项(K值和Value值):
其中key值对应就是e.g Servlet中的WebServlet里填写的项:
而value值就是key对应的类对象(堆中对应的那一块内存空间):
【上面提到的类对象,并非是简单类的实例,而是经过反射得到的Class类文件】
引入反射--->⭐Java---反射--获取类信息⭐-CSDN博客
反射获取类信息的三种方式(对象、类、类的路径):
//反射的三种方式//类的路径Class clazz1=Class.forName("Demo");//类Class clazz2=Demo.class;//类的对象Demo demo=new Demo();Class clazz3=demo.getClass();
而打印这些得到的类信息后进行比对打印:
得到输出都是true:
至于这里为什么返回true,就要提到反射的知识了:
首先,反射是一种获取类信息的能力,可以获取一个类的方法、构造器、变量、父子类、接口......等等信息。
所以,以下就能涵盖一个tomcat运行项目的流程:
假设在一个项目中,我们写了10个servlet动态资源,以及5个HTML静态资源,启动tomcat扫描项目。
首先tomcat扫描时会优先扫描动态资源,通过@WebServlet获取其中的“/FindAllBook”作为Key值,并存入动态资源映射表:
之后value值就是通过key值去访问 FindAllBook类,并且将其反射后的类信息存到value的位置;
即类对象,搭建起动态资源映射表: