HOME> 社区建设> Tomcat 的使用及原理分析(IDEA版)

Tomcat 的使用及原理分析(IDEA版)

文章目录一、预备知识1、软件架构2、资源分类3、网络通信三要素4、服务器软件:5、web 服务器软件二、Tomcat 的使用1、下载2、安装3、卸载4、...

文章目录一、预备知识1、软件架构2、资源分类3、网络通信三要素4、服务器软件:5、web 服务器软件二、Tomcat 的使用1、下载2、安装3、卸载4、启动5、Tomcat 启动可能遇到的问题6、关闭7、配置三、Tomcat 集成 intelliJ IDEA1、首先新建一个项目,选择 `java EE`2、创建完成3、配置 Tomcat4、启动项目5、虚拟目录6、端口7、从一般到特殊8、IDEA 的热部署四、IDEA 集成 Tomcat 分析五、Tomcat 原理分析1、Tomcat 的组成2、Tomcat 的启动流程3、Web 应用的部署方式4、Servlet5、JSP 引擎六、总结

一、预备知识这部分内容时理解 Tomcat 的基础,主要介绍服务器的概念。

1、软件架构代码语言:javascript复制1. C/S:客户端/服务器端

2. B/S:浏览器/服务器端2、资源分类代码语言:javascript复制1. 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源.静态资源可以直接被浏览器解析

* 如: html,css,JavaScript

2. 动态资源:每个用户访问相同资源后,得到的结果可能不一样。称为动态资源。动态资源被访问后,需要先转换为静态资源,在返回给浏览器

* 如:servlet/jsp,php,asp....3、网络通信三要素代码语言:javascript复制1. IP:电子设备(计算机)在网络中的唯一标识。

2. 端口:应用程序在计算机中的唯一标识。 0~65536

3. 传输协议:规定了数据传输的规则

1. 基础协议:

1. tcp:安全协议,三次握手。 速度稍慢

2. udp:不安全协议。 速度快4、服务器软件:服务器就是安装了服务器软件的计算机,它的硬盘比较大,内存比较多,CPU性能好。比如电脑安装了 MySQL 服务器软件,那么这台电脑就可以作为服务器,因为它可以让别的电脑访问到然后操作 MySQL 里的数据。那么安装了 Web 服务器软件,那么这台电脑就可以作为 Web 服务器,让别的电脑访问到。 服务器软件的作用就是可以接收用户的请求,处理请求,做出响应。

5、web 服务器软件在web服务器软件中,可以部署 web 项目,让用户通过浏览器来访问这些项目。

之前我们的角色是用户,将来我们的角色内容提供者,让别人通过浏览器来访问我们写的项目。

动态资源不能够自动运行,他们只能运行在 Web 服务器软件中。

所以也被称为 Web容器,也就是说动态资源必须在容器中才能运行。

而我们要学习的 Tomcat 就是这样一款 Web 服务器软件。

二、Tomcat 的使用1、下载代码语言:javascript复制http://tomcat.apache.org/2、安装代码语言:javascript复制解压压缩包即可。注意:安装目录建议不要有中文和空格解压完之后如图所示:

每个文件夹内容:

3、卸载代码语言:javascript复制删除目录就行了4、启动代码语言:javascript复制1、`bin/startup.bat` ,双击运行该文件即可

2、访问:

浏览器输入:

http://localhost:8080 访问自己

http://别人的ip:8080 访问别人5、Tomcat 启动可能遇到的问题黑窗口一闪而过原因: 没有正确配置JAVA_HOME环境变量解决方案:正确配置JAVA_HOME环境变量启动报错暴力法:找到占用的端口号,并且找到对应的进程,杀死该进程

代码语言:javascript复制netstat -ano温柔法:修改自身的端口号

在下面的文件中修改

代码语言:javascript复制conf/server.xml代码语言:javascript复制

connectionTimeout="20000"

redirectPort="8445" /> 一般会将tomcat的默认端口号修改为80。

80端口号是http协议的默认端口号。

好处:在访问时,就不用输入端口号

6、关闭代码语言:javascript复制1、正常关闭:

bin/shutdown.bat

ctrl+c

2、强制关闭:

点击启动窗口的×7、配置这里才是最重要的

部署项目的方式:

直接将项目放到 webapps 目录下: 将项目打成一个war包,再将war包放置到webapps目录下。war包会自动解压缩

配置 conf/server.xml 文件:

在标签体中配置代码语言:javascript复制

//docBase是项目存放目录

//hehe是虚拟目录在conf\Catalina\localhost创建任意名称的xml文件

在文件中编写:代码语言:javascript复制

//虚拟目录:xml文件的名称代码语言:javascript复制java动态项目的目录结构:

-- 项目的根目录

-- WEB-INF目录:

-- web.xml:web项目的核心配置文件

-- classes目录:放置字节码文件的目录

-- lib目录:放置依赖的jar包三、Tomcat 集成 intelliJ IDEA1、首先新建一个项目,选择 java EE

选择 Tomcat Server :

选择本地的包,选最外层的文件夹就可以了,选好了之后下面的 Tomcat base directory 他会自动生成:

Application Server 选择你本地解压的 Tomcat 的包的位置。

注意这里要勾上

当然不勾也可以,我们也可以手动创建这些包,但是自动生成会方便一些。

2、创建完成创建完成之后的目录结构应该是这样的:

你可以看到,该有的包都已经自动导入了。

3、配置 Tomcat选择 run 下面的 Edit Configurations

点击Template拓展窗口

找到 Tomcat,选择local,

然后配置到你本地的 Tomcat 地址,端口什么的保持原样就可以了

然后点击 Apply OK 关掉就可以了。

4、启动项目配置好了之后选择你的Tomcat,然后启动:

我这里稍微改造了一下 index.html 界面,如图所示:

贴出来代码:

代码语言:javascript复制<%--

Created by IntelliJ IDEA.

User: wsuo

Date: 2020/2/26

Time: 16:39

To change this template use File | Settings | File Templates.

--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

18103330219-王硕

计算机182 ** 1810333**** 男

<%

String a = "abc";

System.out.println(a);

out.println(a + "d");

%>

运行在浏览器端是这样子的:

这样你的IDEA集成 Tomcat 就成功了!

5、虚拟目录 这里稍微多讲一点,关于虚拟目录

如果你细心的话会发现我的项目网址名称很难看:

其中的这个wsProject_war_exploded就是你的虚拟目录

什么意思呢,就是你要在路径名称上加上这句才可以访问到,哪有的同学说你这个太难看了,我可以换个吗,当然可以,你可以随时打开如下图的配置:

点击之后选择 Deployment 然后看下图:

其中这个 Application Context 就是你的虚拟目录,你想改成什么都可以,这样你的访问路径就会发生相应的变化:

比如我如果设置成这样:

那么我访问的时候浏览器的地址就应该是:

代码语言:javascript复制http://localhost:8080/index.jsp如果设置成abcd

那么我访问的时候浏览器的地址就应该是:

代码语言:javascript复制http://localhost:8080/abcd/index.jsp6、端口 再来聊一下端口

细心的你会发现,我们的地址栏冒号后面有个8080,那为什么是8080呢,我填8089行不行?

答案是不行的,但是我们可以配置:

将这个数字改成你想要的的都可以,但是注意可能会有端口占用的问题,这样的话你可以选择我们之前提到的暴力法或者温柔法解决它。

注意一点就是如果你设置成 80端口,那么你就不用填写端口了:

比如上面的地址可以进一步简化为:

代码语言:javascript复制http://localhost/index.jsp因为 80 端口是浏览器的默认端口!

就好像你在 计182 班级里面不用加 计182 的前缀一样,因为大家都知道你是182班的。

7、从一般到特殊OK,我们回过来看这个页面:

路径:

代码语言:javascript复制http://localhost:8080/wsProject_war_exploded/index.jsp我们已经知道端口和虚拟目录了,那么后面的index.jsp是什么鬼呢???

可以换吗?

当然可以,看图:

从图中可以看出,index是直属于web文件夹的,而 web 是一个 webapp 的核心,所以index就是直接在项目根目录下的。

如果我们把index放进一个文件夹里比如file里,那么访问路径就要改为:

代码语言:javascript复制http://localhost:8080/wsProject_war_exploded/file/index.jsp那如果我们不想访问index.jsp呢,比如想访问 hello.html:

贴出来代码:

代码语言:javascript复制

Hello

你好我是Hello.html!

我们新建了web/file/hello.html,于是可以在浏览器输入地址访问:

代码语言:javascript复制http://localhost:8080/wsProject_war_exploded/file/hello.html还有就是 index.jsp,本身比较特殊,就算我们不写也可以访问到,这是因为名字特殊,是一个默认值,这在后面学习 web.xml 中会讲到.

8、IDEA 的热部署如果你跟着我一起做了,相信你一定深有体会,改变文件内容之后一定要重新启动服务器,不然改动效果不会生效。这在开发过程中是很烦的,为了解决这个问题,我们可以使用以下办法(如果你的IDEA使用本来就很卡顿不建议这么做):

修改为上面在每次新建文件的时候就可以不用每次都重启服务器了。

如果你改为:

这样你以后再写 java 代码的时候也可以不用重启服务器了,但是并不推荐这样做,因为java代码的修改次数比较频繁。

由于篇幅原因,有关 Tomecat 的原理部分请看我的另外一篇文章。

四、IDEA 集成 Tomcat 分析IDEA会为每一个 Tomcat 部署的项目单独建立一份配置文件。

那么这个配置文件在哪呢?

我们先启动一个项目:

观察控制台的输出:

观察到有 Using CATALINA_BASE,这个的意思就是使用的工作目录,也就是 工作空间项目。

代码语言:javascript复制C:\Users\13343\.IntelliJIdea2019.2\system\tomcat\Tomcat_8_5_31_wsProject然后我们顺着这个路径去电脑上面查看:

在 conf 里面有一大推配置文件:

这里有很多的配置文件,我们可以打开进行修改端口什么的,但是现在都是 IDEA 磅我们生成好了,通过图形化界面自动生成好了,所以IDEA简化了我们的开发,这就好像计算机指令与图形化界面的关系一样。

然后我们继续往下看:

代码语言:javascript复制打开 \conf\Catalina\localhost发现有一个文件,还是以我们的项目名称命名的!

打开看看:

发现有一个路径,这是Tomcat部署的web项目:

代码语言:javascript复制D:\develop\IDEA_2017\IdeaProjects\lsu_study\wsProject\out\artifacts\wsProject_war_exploded在电脑中打开:

这就是我们之前所说的第三种项目的部署方式,这里IDEA又帮我们自动生成了。

就是这个:

在conf\Catalina\localhost创建任意名称的xml文件

他就相当于在 webapps 目录下放了一个 war 包。

你工作空间的out目录下面就是Tomcat的项目部署的地方。

这个才是 Tomcat 真正访问的项目。

而 Tomcat部署的web项目 目录下会有一个 classes ,这里的文件从哪里来呢?

从你的项目的 src 目录下来的。例子中的项目 src 目录为空,所以没有 classes 文件夹。

仔细看上面两个目录,你会发现,web目录其实就是 Tomcat部署的web项目 的根目录!

五、Tomcat 原理分析1、Tomcat 的组成如下图:

Server: Tomcat 封装的、对外提供完整的、基于组件的 web 服务,包含 Connectors、Container 两个核心组件,以及多个功能组件,各个 Service 之间是独立的,但是共享 同一 JVM 的资源;

Connector: Tomcat 与外部世界的连接器,监听固定端口接收外部请求,传递给 Container,并将 Container 处理的结果返回给外部;

Container: Catalina,Servlet 容器,内部有多层容器组成,用于管理 Servlet 生命周期,调用 servlet 相关方法。

Loader: 封装了 Java ClassLoader,用于 Container 加载类文件;

Realm: Tomcat 中为 web 应用程序提供访问认证和角色管理的机制;

JMX: Java SE 中定义技术规范,是一个为应用程序、设备、系统等植入管理功能的框架,通过 JMX 可以远程监控 Tomcat 的运行状态;

Jasper: Tomcat 的 Jsp 解析引擎,用于将 Jsp 转换成 Java 文件,并编译成 class 文件。

Session: 负责管理和创建 session,以及 Session 的持久化(可自定义),支持 session 的集群。

Pipeline: 在容器中充当管道的作用,管道中可以设置各种 valve(阀门),请求和响应在经由管 道中各个阀门处理,提供了一种灵活可配置的处理请求和响应的机制。

Naming: 命名服务,JNDI, Java 命名和目录接口,是一组在 Java 应用中访问命名和目录服务的 API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象,目录服务也是一种命名服务,对象不但有名称,还有属性。Tomcat 中可以使用 JNDI 定义数据源、配置信息,用于开发与部署的分离。

Container的组成:

Engine: Servlet 的顶层容器,包含一 个或多个 Host 子容器;

Host: 虚拟主机,负责 web 应用的部 署和 Context 的创建;

Context: Web 应用上下文,包含多个 Wrapper,负责 web 配置的解析、管理所有的 Web 资源;

Wrapper: 最底层的容器,是对 Servlet 的封装,负责 Servlet 实例的创建、执行和销毁。

2、Tomcat 的启动流程1、启动从 Tomcat 提供的 start.sh 脚本开始

我们点击这个:

shell 脚本会调用 Bootstrap 的 main 方法,实际调用了 Catalina 相应的 load、start 方法。

2、解析配置文件

然后 load 等方法会读取 conf 文件夹下的配置文件:

在解析的过程中会根据 xml 中的关系 和配置信息来创建容器,并设置相关的属性。接着 Catalina 会调用 StandardServer 的 init 和 start 方法进行容器的初始化和启动。

3、生命周期

按照 xml 的配置关系,server 的子元素是 service,service 的子元素是顶层容器 Engine,每层容器有持有自己的子容器,而这些元素都实现了生命周期管理的各个方法,因此就很容易的完成整个容器的启动、关闭等生命周期的管理。

4、监听端口

StandardServer 完成 init 和 start 方法调用后,会一直监听来自 8005 端口(可配置),如果接收到 shutdown 命令,则会退出循环监听,执行后续的 stop 和 destroy 方法,完成 Tomcat 容器的 关闭。同时也会调用 JVM 的 Runtime.getRuntime() .addShutdownHook 方法,在虚拟机意外退出的时候来关闭容器。

5、ContainerBase

所有容器都是继承自 ContainerBase,基类中封装了容器中的重复工作,负责启动容器相关的组 件 Loader、Logger、Manager、Cluster、Pipeline,启动子容器(线程池并发启动子容器,通过 线程池 submit 多个线程,调用后返回 Future 对象,线程内部启动子容器,接着调用 Future 对象 的 get 方法来等待执行结果)。

3、Web 应用的部署方式代码语言:javascript复制catalina.home 是 安装目录

catalina.base 是 工作目录 即 webappsServer.xml:

配置 Host 元素;指定 appBase 属性;配置 Context 元素;指定 docBase 元素;指定 web 应用的路径HostConfig 监听了 StandardHost 容器的事件,在 start 方法中解析上述配置文件:

扫描并解析 webapps 下的所有文件夹和 war 包,解析各个应用的 META-INF / context.xml,并创建 StandardContext,并将 Context 加入到 Host 的子容器中。

ContextConfig 解析 context.xml 顺序:

先解析全局的配置 config/context.xml

然后解析 Host 的默认配置 EngineName/HostName/context.xml.default

最后解析应用的 META-INF/context.xml

ContextConfig 解析 web.xml 顺序:

先解析全局的配置 config/web.xml

然后解析 Host 的默认配置 EngineName/HostName/web.xml.default 接着解析应用的 WEB-INF/web.xml

扫描应用 WEB-INF/lib/下的 jar 文件,解析其中的 META-INF/web-fragment.xml 最后合并 xml 封装成 WebXml,并设置 Context

4、ServletServlet 是用 Java 编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。

它由 wrapper 封装;生命周期如下:

请求到达 server 端,server 根据 url 映射到相应的 Servlet判断 Servlet 实例是否存在,不存在则加载和实例化 Servlet 并调用 init 方法Server 分别创建 Request 和 Response 对象,调用 Servlet 实例的 service 方法(service 方法内部会根据 http 请求方法类型调用相应的 doXXX 方法)doXXX 方法内为业务逻辑实现,从 Request 对象获取请求参数,处理完毕之后将结果通过 response 对象返回给调用方当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方 法。请求处理过程:

根据 server.xml 配置的指定的 connector 以及端口监听 http、或者 ajp 请求请求到来时建立连接,解析请求参数,创建 Request 和 Response 对象,调用顶层容器 pipeline 的 invoke 方法容器之间层层调用,最终调用业务 servlet 的 service 方法Connector 将 response 流中的数据写到 socket 中Pipeline 与 Valve :

Pipeline 可以理解为现实中的管道,Valve 为管道中的阀门,Request 和 Response 对象在管道中 经过各个阀门的处理和控制。

每个容器的管道中都有一个必不可少的 basic valve,其他的都是可选的,basic valve 在管道中最 后调用,同时负责调用子容器的第一个 valve。各层容器对应的 basic valve 分别是 StandardEngineValve、StandardHostValve、 StandardContextValve、StandardWrapperValve。5、JSP 引擎JSP 生命周期:

编译阶段:servlet 容器编译 servlet 源文件,生成 servlet 类初始化阶段:加载与 JSP 对应的 servlet 类, 创建其实例,并调用它的初始化方法执行阶段:调用与 JSP 对应的 servlet 实例的 服务方法销毁阶段:调用与 JSP 对应的 servlet 实例的 销毁方法,然后销毁 servlet 实例如图,JSP文件会被解析为 servlet 类。

这是随便拿的一个栗子,将上面的文件打开,可以看到有一部分文件正是将HTML标签写入到页面上。

六、总结看完了之后是不是感觉 Tomcat 不是那么神奇了?甚至感觉自己可以手写一个 Tomcat?

对,其实他就是一个服务器软件,我们在浏览器输入一个地址,完了之后能访问到页面,这里面 Tomcat 为我们做了很多工作,比如这个地址:

代码语言:javascript复制http://localhost:8080/abcd/index.jsp模拟一下浏览器访问哈:

首先由 localhost 找到了对应的主机,也就是服务器;然后由 8080 找到了对应的应用程序,也就是 Tomcat ;通过abcd可以找到当前 Tomcat 下面部署的项目;最后那个index.jsp就是资源名称。


小红书上的老牌「小红包」怎么又火了? lol 4800英雄,《英雄联盟》4800的英雄都有谁?