【JavaWeb】Tomcat底层机制和Servlet运行原理

🎄欢迎来到@dandelionl_的csdn博文,本文主要讲解Java web中Tomcat底层机制和Servlet的运行原理的相关知识🎄


🌈我是dandelionl_,一个正在为秋招和算法竞赛做准备的学生🌈
🎆喜欢的朋友可以关注一下,下次更新不迷路🎆

 Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑🌒🌓🌔🌕  

一. 一图明理


 二. 概念

Tomcat是一个开源的Java Web服务器,它是基于Java Servlet和JavaServer Pages(JSP)技术的。下面是关于Tomcat底层机制和Servlet运行原理的简要说明:

  1. Tomcat底层机制:

    • 网络通信:Tomcat使用Java的Socket API来监听特定的端口(通常是8080),接收来自客户端的HTTP请求。
    • 线程池:Tomcat使用线程池来处理并发的请求当有新的请求到达时,Tomcat会从线程池中获取一个空闲线程来处理该请求,这样可以提高处理效率。
    • 生命周期管理:Tomcat负责管理Servlet和其他Web组件的生命周期,包括初始化、请求处理和销毁等阶段。(init(), run())
    • 请求处理管道:Tomcat通过请求处理管道来处理HTTP请求。请求经过一系列的处理器,如身份验证、日志记录和安全检查等,最终被交给适当的Servlet进行处理。(handle())
    • 连接池:Tomcat使用连接池来管理与数据库的连接。这样可以提高性能,并避免频繁地创建和销毁数据库连接。(handle())
  2. Servlet运行原理:

    • Servlet容器:Tomcat是一个Servlet容器它负责加载、初始化和管理Servlet。当Tomcat启动时,它会读取配置文件(如web.xml)来确定需要加载的Servlet类
    • 生命周期:每个Servlet都有自己的生命周期,包括初始化、请求处理和销毁等阶段。Tomcat会在适当的时间调用Servlet的生命周期方法(如init()、service()和destroy())。
    • 请求处理:当Tomcat接收到HTTP请求时,它会根据请求的URL找到对应的Servlet并将请求转发给该Servlet进行处理Servlet通过HttpServletRequest对象获取请求的信息,并通过HttpServletResponse对象发送响应给客户端
    • 多线程处理:Tomcat使用多线程来处理并发请求每个请求都被分配给一个独立的线程进行处理,这样可以同时处理多个请求,提高服务器的性能

三. 容器的理解 

在tomcat底层实现中, servlet作为容器, 实现可以理解为HashMap, 键是servlet-name值是servlet-class, 而HashMap就是一个容器, 从容器中得到一个servlet实例, 对其进行初始化, 供web使用, 调用其中的service()方法, service()方法对HTTP请求的method进行判断, 对每个相应的method都有相应的do方法, 可以使用.


四. 案例

不用tomcat以及servlet实现

五. 代码分析和代码实现

 

 

 

LxbRequestHandle类

package com.lxb.tomcat.handle;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 13:22:00
//@Authors : 罗雄波
//@File : LxbRequestHandle.java
//@Software : IntelliJ IDEAimport com.lxb.tomcat.LxbTomcatV3;
import com.lxb.tomcat.http.LxbHttpRequest;
import com.lxb.tomcat.http.LxbHttpResponse;
import com.lxb.tomcat.servlet.LxbHttpServlet;
import com.lxb.tomcat.utils.WebUtils;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;public class LxbRequestHandle implements Runnable{private Socket accept;public LxbRequestHandle(Socket socket) {this.accept = socket;}public void run() {try {LxbHttpRequest request = new LxbHttpRequest(accept);LxbHttpResponse response = new LxbHttpResponse(accept.getOutputStream());String uri = request.getUri();if(WebUtils.isHtml(uri)) {System.out.println(uri.substring(1));String resp = WebUtils.readFile(uri.substring(1));String responseInfo = LxbHttpResponse.respHeader + resp;OutputStream outputStream = response.getOutputStream();outputStream.write(responseInfo.getBytes());outputStream.flush();outputStream.close();accept.close();return;}String servletName = LxbTomcatV3.servletMapping.get(uri);if(servletName == null) {servletName = "";}LxbHttpServlet servlet = LxbTomcatV3.servlet.get(servletName);if(servlet != null) {servlet.service(request, response);} else {String resp = LxbHttpResponse.respHeader + "<h1>404 not found!!!</h>";OutputStream responseOutputStream = response.getOutputStream();responseOutputStream.write(resp.getBytes());responseOutputStream.flush();responseOutputStream.close();}accept.close();} catch (Exception e) {throw new RuntimeException(e);} finally {if (accept != null) {try {accept.close();} catch (IOException e) {e.printStackTrace();}}}}
}

LxbHttpRequest和LxbHttpResponse

package com.lxb.tomcat.http;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 14:59:24
//@Authors : 罗雄波
//@File : LxbHttpRequest.java
//@Software : IntelliJ IDEAimport java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.HashMap;public class LxbHttpRequest {private Socket socket;private String method;private String uri;private HashMap<String, String> parameterMapping = new HashMap<String, String>();public LxbHttpRequest(Socket socket) {this.socket = socket;try {ParseProcess();} catch (Exception e) {throw new RuntimeException(e);}}public void ParseProcess() throws Exception {BufferedReader reader =new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));String temp;temp = reader.readLine();//        GET /cal.html HTTP/1.1String[] request = temp.split(" ");method = request[0];int index = request[1].indexOf("?");if (index == -1) {uri = request[1];} else {uri = request[1].substring(0, index);String parameterPair = request[1].substring(index + 1);String[] parameters = parameterPair.split("&");if (parameters[0] != null && !parameters[0].equals("")) {for (String parameter : parameters) {String[] split = parameter.split("=");if(split.length == 2) {parameterMapping.put(split[0], split[1]);}}}}}public String getMethod() {return method;}public String getUri() {return uri;}public String getParameter(String key) {if(parameterMapping.get(key) != null) {return parameterMapping.get(key);} else {return "";}}@Overridepublic String toString() {return "LxbHttpRequest" +"{ method = " + method +", uri = " +  uri +", parameter = " + parameterMapping +"}";}
}
package com.lxb.tomcat.http;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 15:49:29
//@Authors : 罗雄波
//@File : LxbHttpResponse.java
//@Software : IntelliJ IDEAimport java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;public class LxbHttpResponse {private OutputStream outputStream = null;public static final String respHeader = "HTTP/1.1 200 OK\r\n" +"Content-Type: text/html;charset=utf-8\r\n\r\n";public LxbHttpResponse(OutputStream outputStream) {this.outputStream = outputStream;}public OutputStream getOutputStream() {return outputStream;}
}

LxbTomcat

package com.lxb.tomcat;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 15:37:29
//@Authors : 罗雄波
//@File : LxbTomcatV3.java
//@Software : IntelliJ IDEAimport com.lxb.tomcat.handle.LxbRequestHandle;
import com.lxb.tomcat.servlet.LxbHttpServlet;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;public class LxbTomcatV3 {public static ConcurrentHashMap<String, LxbHttpServlet> servlet =new ConcurrentHashMap<String, LxbHttpServlet>();public static ConcurrentHashMap<String, String> servletMapping =new ConcurrentHashMap<String, String>();public static void main(String[] args) throws Exception {LxbTomcatV3 lxbTomcatV3 = new LxbTomcatV3();lxbTomcatV3.Init();lxbTomcatV3.run();}public void run() {try {ServerSocket socket = new ServerSocket(8080);while (!socket.isClosed()) {Socket accept = socket.accept();LxbRequestHandle requestHandle = new LxbRequestHandle(accept);new Thread(requestHandle).start();}} catch (IOException e) {throw new RuntimeException(e);}}@Testpublic void Init() {String path = LxbTomcatV3.class.getResource("/").getPath();
//        System.out.println(path);
//   该类的路径 /D:/NewExecllction/exicese%20code/lxb-tomcat/target/classes/com/lxb/tomcat/
//   根路径    /D:/NewExecllction/exicese%20code/lxb-tomcat/target/classes/SAXReader saxReader = new SAXReader();try {Document document = saxReader.read(new File(path + "web.xml"));
//            System.out.println(document);Element rootElement = document.getRootElement();List<Element> elements = rootElement.elements();for (Element element : elements) {if ("servlet".equalsIgnoreCase(element.getName())) {Element servletName = element.element("servlet-name");Element servletClass = element.element("servlet-class");servlet.put(servletName.getText(), (LxbHttpServlet) Class.forName(servletClass.getText().trim()).newInstance());} else if ("servlet-mapping".equalsIgnoreCase(element.getName())) {Element servletName = element.element("servlet-name");Element servletUrl = element.element("url-pattern");servletMapping.put(servletUrl.getText(), servletName.getText());}}} catch (Exception e) {e.printStackTrace();}System.out.println(servlet);System.out.println(servletMapping);}@Testpublic void test() {String path = LxbTomcatV3.class.getResource("/").getPath();System.out.println(path + "web.xml");}
}

WebUtils

package com.lxb.tomcat.utils;
//-*- code = utf-8 -*-
//@Time : 2023-07-19 16:00:33
//@Authors : 罗雄波
//@File : WebUtils.java
//@Software : IntelliJ IDEAimport org.junit.Test;import java.io.*;public class WebUtils {public static int parseInt(String strNum, int defaultVal) {try {return Integer.parseInt(strNum);} catch (NumberFormatException e) {System.out.println(strNum + "数字格式异常, 无法包装");}return defaultVal;}public static boolean isHtml(String uri) {return uri.endsWith(".html");}public static String readFile(String filename) {String path = com.lxb.tomcat.utils.WebUtils.class.getResource("/").getPath();StringBuilder stringBuffer = new StringBuilder();try {System.out.println(path + filename);BufferedReader bufferedReader = new BufferedReader(new FileReader(path + filename));String buffer = null;while ((buffer = bufferedReader.readLine()) != null && !buffer.equals("")) {stringBuffer.append(buffer);}} catch (Exception e) {e.printStackTrace();}return stringBuffer.toString();}
}

LxbCalServlet

package com.lxb.tomcat.servlet;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 16:14:24
//@Authors : 罗雄波
//@File : LxbCalServlet.java
//@Software : IntelliJ IDEAimport com.lxb.tomcat.http.LxbHttpRequest;
import com.lxb.tomcat.http.LxbHttpResponse;
import com.lxb.tomcat.utils.WebUtils;import java.io.IOException;
import java.io.OutputStream;public class LxbCalServlet extends LxbHttpServlet {@Overridepublic void doGet(LxbHttpRequest request, LxbHttpResponse response) {doPost(request, response);}@Overridepublic void doPost(LxbHttpRequest request, LxbHttpResponse response) {int num1 = WebUtils.parseInt(request.getParameter("num1"), 0);int num2 = WebUtils.parseInt(request.getParameter("num2"), 0);int result = num1 + num2;OutputStream outputStream = response.getOutputStream();String resp = LxbHttpResponse.respHeader + "<h1>求和: " + num1 + "+" + num2 + " = " + result + "</h>";try {outputStream.write(resp.getBytes());outputStream.flush();outputStream.close();} catch (IOException e) {throw new RuntimeException(e);}}public void init() throws Exception {}public void destroy() {}
}

LxbServlet

package com.lxb.tomcat.servlet;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 16:09:43
//@Authors : 罗雄波
//@File : LxbServlet.java
//@Software : IntelliJ IDEAimport com.lxb.tomcat.http.LxbHttpRequest;
import com.lxb.tomcat.http.LxbHttpResponse;import java.io.IOException;public interface LxbServlet {void init() throws Exception;void service(LxbHttpRequest request, LxbHttpResponse response) throws IOException;void destroy();
}

LxbHttpServlet

package com.lxb.tomcat.servlet;
//-*- code = utf-8 -*-
//@Time : 2023-07-20 16:11:02
//@Authors : 罗雄波
//@File : lxbHttpServlet.java
//@Software : IntelliJ IDEAimport com.lxb.tomcat.http.LxbHttpRequest;
import com.lxb.tomcat.http.LxbHttpResponse;import java.io.IOException;public abstract class LxbHttpServlet implements LxbServlet{public void service(LxbHttpRequest request, LxbHttpResponse response) throws IOException {if(request.getMethod().equals("GET")) {this.doGet(request, response);} else if(request.getMethod().equals("POST")) {this.doPost(request, response);}}public void doGet(LxbHttpRequest request, LxbHttpResponse response) {}public void doPost(LxbHttpRequest request, LxbHttpResponse response) {}
}

 六. 注意

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIA实验二

实验要求&#xff1a; 1.R2为ISP&#xff0c;只能配置IP 2.R1-R2之间为HDLC封装 3.R2-R3之间为PPP封装&#xff0c;pap认证&#xff0c;R2为主认证方 4.R2-R4之间为PPP封装&#xff0c;chap认证&#xff0c;R2为主认证方 5.R1、R2、R3构建MGRE&#xff0c;仅R1的IP地址固定…

【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

Nginx学习&#xff1a;HTTP核心模块&#xff08;九&#xff09;浏览器缓存与try_files 浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置&#xff0c;这一块也是 HTTP 的基础知识。之前我们就一直在强调&#xff0c;学习 Nginx 需要的就是各种网络相关的基础知识&…

AndroidStudio设计一个计算器

界面设计 activity_calcuator.xml 设计&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto&qu…

3ds Max图文教程: 创建致命的冠状病毒动画

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 病毒建模 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 在透视视口中创建一个半径为 50&#xff0c;线段为 20 的 GeoSphere。 创建地球 步骤 3 打开修改器列表并将置换修改器应用于地理 球。 置换…

【STL】模拟实现反向迭代器

目录 1. 读源码 2. 搭建框架 3. 迭代器的操作 operator*() operator->() operator() operator--() operator!() 4. 实现 list 的反向迭代器 5. 实现 vector 的反向迭代器 6. 源码分享 写在最后&#xff1a; 1. 读源码 我们之前实现的 vector&#xff0c;list…

类加载机制,类加载顺序

类加载顺序 ①类加载从上往下执行&#xff0c;依次执行静态的初始化语句和初始化块&#xff0c;而且类加载优先于对象创建。&#xff08;静态初始化语句和初始化块只加载一次&#xff09; ②创建本类的对象时&#xff0c;从上往下执行一次非静态的初始化语句和初始化块&#…

Unity《勇士传说》开发日记:如何制作可互动标识

要实现的需求&#xff1a; 在游戏当中&#xff0c;我们的主角走到宝箱前&#xff0c;可以将宝箱打开&#xff0c;走到洞穴口可以进入下一个场景&#xff0c;此时需要有个互动标识来提示用户。如图所示&#xff1a; 当角色走到宝箱前&#xff0c;弹出互动标识提示用户按下E键可…

关于idea如何成功运行web项目

导入项目 如图 依次选择 file - new - Project from Existing Sources 选择存放的项目目录地址 如图 导入完成 点击ok 如图 依次选择 Create project from existing sources 点击next如图 &#xff0c;此处默认即可 点击 next如图 点击next有该提示 是因为之前导入过…

jmeter接口测试、压力测试简单实现

jmeter测试的组件执行顺序&#xff1a; 测试计划—>线程组—>配置元件—>前置处理器—>定时器—>逻辑控制器—>取样器—>后置处理器—>断言—>监听器 组件的作用范围&#xff1a; 同级组件同级组件下的子组件父组件 目前市面上的三类接口 1、基…

10分钟带你实现一个Android自定义View:带动画的等级经验条

先展示一下静态效果图 介绍一下我们的实现流程&#xff1a; 首先整个经验条有一个圆角边框的背景打底&#xff1b;然后给经验条绘制一条轨道&#xff0c;让用户比较直观地看到总进度的长度&#xff1b;在轨道的上层绘制我们的渐变色经验条&#xff1b;在经验条的上层绘制等级…

用html+javascript打造公文一键排版系统8:附件及标题排版

最近工作有点忙&#xff0c;所 以没能及时完善公文一键排版系统&#xff0c;现在只好熬夜更新一下。 有时公文有包括附件&#xff0c;招照公文排版规范&#xff1a; 附件应当另面编排&#xff0c;并在版记之前&#xff0c;与公文正文一起装订。“附件”二字及附件顺序号用3号黑…

Python(四十六)列表

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

【Java基础教程】(四十八)集合体系篇 · 上:全面解析 Collection、List、Set常用子接口及集合元素迭代遍历方式~【文末送书】

Java基础教程之集合体系 上 &#x1f539;本章学习目标1️⃣ 类集框架介绍2️⃣ 单列集合顶层接口&#xff1a;Collection3️⃣ List 子接口3.1 ArrayList 类&#x1f50d; 数组&#xff08;Array&#xff09;与列表&#xff08;ArrayList&#xff09;有什么区别?3.2 LinkedL…

在 ArcGIS Pro 中使用 H3 创建蜂窝六边形

H3是Uber开发的分层索引系统,它使用六边形来平铺地球表面。H3在二十面体(一个具有20个三角形面和12个顶点的形状)上构建其六边形网格。由于仅用六边形不可能平铺二十面体,因此每个分辨率需要12个五边形来完成网格。分层索引网格意味着每个六边形都可以细分为子单元六边形。…

给jupter设置新环境

文章目录 给jupternotebook设置新环境遇到的报错添加路径的方法 给jupternotebook设置新环境 # 先在anaconda界面新建环境 conda env list # 查看conda prompt下的有的环境变量 带星号的是当前活跃的 activate XXXX pip install ipykernel ipython ipython kernel install --u…

如何安装mmcv?官网解答

pip install -U openmim mim install mmcv

【高分论文密码】大尺度空间模拟预测与数字制图教程

详情点击链接&#xff1a;【高分论文密码】大尺度空间模拟预测与数字制图 一&#xff0c;R语言空间数据及数据挖掘关键技术 1、R语言空间数据及应用特点 1)R语言基础与数据科学 2)R空间矢量数据 3)R栅格数据 2、R语言空间数据挖掘关键技术 二&#xff0c;R语言空间数据高…

素描基础知识

素描基础入门 1.基础线条 1.1 握笔姿势及长线条 2.排线 2.1 不同姿势画排线 2.1.1 姿势画排线 2.1.2 用手腕画排线 2.1.3 小拇指画排线 2.1.4 叠加排线 2.1.5交叉排线 2.2 纸张擦法 2.3 排线学习榜样 2.4 四种常见的排线 3、定向连线 4、一点透视 4.1 透视的规律 4.2 焦点透视…

SpringCloudAlibaba:服务网关之Gateway的cors跨域问题

目录 一&#xff1a;解决问题 二&#xff1a;什么是跨域 三&#xff1a;cors跨域是什么&#xff1f; 一&#xff1a;解决问题 遇到错误&#xff1a; 前端请求时报错 解决&#xff1a; 网关中添加配置文件&#xff0c;注意springboot版本&#xff0c;添加配置。 springboo…