引入
Tomcat 在处理HTTP请求时,会根据一系列规则和配置来判断该请求是想要获取动态资源还是静态资源。
为什么要对请求进行判断?
Tomcat 判断HTTP请求是动态请求还是静态请求的主要目的是确定如何生成并返回响应内容。静态请求通常意味着服务器只需读取并返回文件系统中的某个文件,而动态请求则意味着服务器需要执行一些代码或逻辑来生成响应。
静态资源和动态资源是什么?(定义)
那么怎么去判断呢?
引用(网络资源回答)
URL匹配:
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类文件】
反射获取类信息的三种方式(对象、类、类的路径):
//反射的三种方式//类的路径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的位置;
即类对象,搭建起动态资源映射表: