手写简单的tomcat

首先,Tomcat是一个软件,所有的项目都能在Tomcat上加载运行,Tomcat最核心的就是Servlet集合,本身就是HashMap。Tomcat需要支持Servlet,所以有servlet底层的资源:HttpServlet抽象类、HttpRequest和HttpResponse,否则我们无法新建Servlet。

http协议:客户端和用户端进行请求和响应的过程:

这样我们就可以在webapps写项目了,一个项目有两大资源:servlet资源和静态资源,servlet本身是java类,我们让它调用doGet和doPost方法,必须继承HttpServlet,同时也需要@WebServlet注解,那么在Tomcat中就必须要有@WebServlet注解的实现,如果没有@WebServlet,我们就无法拿到相应的注解。这样我们就能成功搭建起Servlet资源。

当Http请求打过来之后,先打到socket上,处理Http请求,其本身就是连接器,从请求上能获取到请求路径和请求方法。先获取到请求路径,判断servlet容器中是否含有相同路径,如果有,再获取请求方法,判断是doGet还是doPost。


简易版tomcat的核心原理

真正的Tomcat很复杂,但它的最核心功能可以简化为:

  1. 监听HTTP请求(Socket 绑定 8080 端口)
  2. 解析HTTP请求(读取请求头、请求体)
  3. 找到对应的Servlet处理请求(反射调用 service() 方法)
  4. 返回HTTP响应(写回响应头和HTML)

手写tomcat

首先,定义Servlet接口

public interface servlet {public void service(HttpServletRequest request, HttpServletResponse response) throws IOException;
}

其次,定义request和response

public class HttpServletRequest {private String method;private String url;//............public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}
}public class HttpServletResponse {//输出流private OutputStream outputStream;public HttpServletResponse(OutputStream outputStream){this.outputStream = outputStream;}/*** 返回动态资源* @param context*/public void write(String context) throws IOException {//System.out.println(context);outputStream.write(context.getBytes());}/*** 返回静态资源*/public void writeHtml(String path) throws Exception {String resourcesPath = FileUtil.getResoucePath(path);File file = new File(resourcesPath);if(file.exists()){//静态文件存在System.out.println("静态文件存在");FileUtil.writeFile(file,outputStream);}else {System.out.println("静态文件不存在");write(ResponseUtil.getResponseHeader404());}}}

然后,实现一个Httpserver

public class MyTomcat {static HashMap<String, HttpServlet> routes = TomcatRoute.routes; //tomcat路由\/*** 分发器*/public  void dispatch(HttpServletRequest request ,HttpServletResponse response) throws IOException {System.out.println("URL: " + request.getUrl());HttpServlet servlet = routes.get(request.getUrl());  //if(servlet!=null){ //说明请求的就是我们的servletSystem.out.println("找到匹配的Servlet: " + servlet.getClass().getName());servlet.service(request,response);}}/*** socket 启动* @throws IOException*/public  void start() throws IOException {ServerSocket serverSocket = new ServerSocket(8080);  //1.指定监听的端口号//2.对端口进行监听while (true){Socket socket = serverSocket.accept();//阻塞监听//3.打开输入流,解析客户端发来的内容InputStream inputStream = socket.getInputStream(); //输入流HttpServletRequest request = new HttpServletRequest();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));  //将字节流转换成字符流String str = reader.readLine();//分割request.setMethod(str.split("\\s")[0]);request.setUrl(str.split("\\s")[1]);//4.打开输出流OutputStream outputStream = socket.getOutputStream();HttpServletResponse response = new HttpServletResponse(outputStream);//分发器dispatch(request,response);socket.close();//socket在这里关闭}}//socketpublic static void main(String[] args) throws IOException {MyTomcat myTomcat = new MyTomcat();myTomcat.start();}
}

然后,自定义一个Servlet

@CYServlet(url = "/myServlet")
public class MyFirstServlet extends HttpServlet {@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {super.doPost(request, response);}@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {System.out.println("Hello World!");System.out.println("Servlet实例: " + this);response.write(ResponseUtil.getResponseHeader200("hello world  hhhhh"));}
}

最后,启动服务并测试

public static void main(String[] args) throws IOException {MyTomcat myTomcat = new MyTomcat();myTomcat.start();}

访问浏览器localhost:8080会得到:

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

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

相关文章

智能体赋能效率,企业知识库沉淀价值:UMI企业智脑的双轮驱动!

智能体企业知识库&#xff1a;UMI企业智脑的核心功能与价值 在人工智能技术飞速发展的今天&#xff0c;企业智能化转型已经成为不可逆转的趋势。作为企业级AI智能体开发平台的佼佼者&#xff0c;优秘智能推出的UMI企业智脑&#xff0c;以其强大的智能体开发能力和全面的企业知…

与 PyCharm 官方沟通解决开发环境问题记录(进展:官方已推出2个新的修复版本)

​​​​​​主题&#xff1a;有关 PyCharm 中终端和环境激活问题的反馈&#xff1a;PY-81233 前言 目前进展&#xff1a; 官方已有2个修复版本推出测试。 更新方法&#xff1a; 使用JetBrains Toolbox App&#xff0c;如下图所示&#xff0c;从“其他版本”进入查看更新。…

LINUX安装运行jeelowcode后端项目(命令行)

环境准备 运行环境&#xff1a;JDK1.8开发工具&#xff1a; Idea、Maven默认已启动中间件&#xff1a;&#xff08;推荐使用宝塔&#xff09;Mysql8.0、Redis、Minio第一步&#xff1a;下载JeelowCode项目并导入IDEA中 第二步&#xff1a;导入数据库文件到mysql中&#xff0c;…

Android开机向导定制(2)开机向导配置

先贴lineage_wizard_script_user.xml的代码&#xff1a; <WizardScript xmlns:wizard"http://schemas.android.com/apk/res/com.google.android.setupwizard"wizard:firstAction"welcome"><WizardAction wizard:uri"intent:#Intent;actiono…

守护电动“心脏”!仿真APP在汽车电池包随机振动分析中的应用

汽车电动化、智能化、绿色化发展已成为全球各国应对气候变化、实现低碳发展的共同选择。在此背景下&#xff0c;新能源汽车持续高速发展。电池包作为新能源汽车的“心脏”&#xff0c;是其主要动力来源&#xff0c;直接影响车辆的续航里程与行驶安全。电池包结构的安全可靠性对…

实习面经(JAVA)

目录 锁升级 notify和notifyAll区别 Sleep和Wait的区别 ArrayList和ListedList区别 HashMap扩容原理 ConcurrentHashMap StringBuffer 和 StringBuilder 事务等级 索引结构 三次握手四次挥手&#xff0c;为什么是三次和四次 Java中重写和重载的区别和应用场景 ArrayLis…

计算机网络-WebSocket/DNS/Cookie/Session/Token/Jwt/Nginx

文章目录 WebSocketDNS什么是dns域名解析底层协议 cookie/sessionToken/JWTNginx WebSocket 一种网络通信协议&#xff0c;允许在单个 TCP&#xff08;半双工&#xff09; 连接上进行全双工通信&#xff08;客户端和服务器可同时双向传输数据&#xff09;。 HTTP是基于请求-响…

单片机如何快速实现查看实时数据

在用 Keil 做调试的时候&#xff0c;最让人头秃的是什么&#xff1f; 不是写代码的BUG&#xff0c;而是&#xff1a;这个条件变量是什么情况&#xff1f;为什么没进入这个判断&#xff1f;我代码跑到哪里了&#xff1f; 其实本质上都是通过变量判断代码的执行顺序有没有问题 …

vue3:横线无限滚动(向左/向右),自定义UI

子组件 <template><div class"single-scroll-container" ref"container" mouseenter"pause" mouseleave"resume"><divclass"single-scroll-content":style"{ transform: translateX(${translateX}px) }…

Anthropic公司近日发布了两款新一代大型语言模型Claude Opus 4与Claude Sonnet 4

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【机器人】复现 Embodied-Reasoner 具身推理 | 具身任务 深度推理模型 多模态场景 长远决策 多轮互动

Embodied-Reasoner 是一个多模态具身模型&#xff0c;它将 o1 的深度推理能力扩展到具身交互任务。 可以在 AI2THOR 仿真中执行复杂的任务&#xff0c;例如搜索隐藏物体、操纵 和 运输物品 具有以下的功能&#xff1a; &#x1f914; 深度推理能力&#xff0c;例如分析、空间…

使用 Qemu 调试 LoongArch 应用程序

1.编译 Qemu OS:Ubuntu 22.04 下载Qemu源码 git clone --depth1 https://gitlab.com/qemu-project/qemu.git编译 cd qemu mkdir build cd build ../configure --target-listloongarch64-linux-user,loongarch64-softmmu --prefixpwd/__install make && make instal…

Unity 游戏优化(持续更新中...)

垃圾回收 是什么&#xff1f; 垃圾回收&#xff08;Garbage Collection&#xff09;GC 工作机制 1、Unity 为用户生成的代码和脚本采用了自动内存管理。 2、小块数据&#xff08;如值类型的局部变量&#xff09;分配在栈上。大块数据和长期存储分配在托管堆上。 3、垃圾收集…

python和java差异:关键数据类型与容器

2.0. 对象的类型&#xff1a;可变 (Mutable) 与不可变 (Immutable) 在Python中&#xff0c;理解对象的可变性 (mutability) 是至关重要的&#xff0c;它影响着变量如何被修改、函数参数如何传递以及数据结构的行为。 不可变对象 (Immutable Objects): 大白话定义&#xff1a;…

DAY 33

知识点回顾&#xff1a; 1. PyTorch和cuda的安装 2. 查看显卡信息的命令行命令&#xff08;cmd中使用&#xff09; 3. cuda的检查 4. 简单神经网络的流程 a. 数据预处理&#xff08;归一化、转换成张量&#xff09; b. 模型的定义 i. 继承nn.Module类 ii. 定义…

Minktec 柔性弯曲传感器,灵敏捕捉坐姿弓背、精准监测行走姿态,守护儿童背部健康,为科学健身提供数据支撑,开启职业健康与背痛 AI 干预新方向。

Minktec弯曲形变传感器通过创新的技术设计&#xff0c;为各种弯曲和形变检测需求提供了精确的解决方案。其核心技术基于薄膜柔性传感器的应用&#xff0c;能够捕捉物体在三维空间中的动态变化。传感器内部结合了多点排列的应变元件和专有算法&#xff0c;实现了形状的实时重建。…

快递鸟接口费用解析:中小电商成本控制方案

中小电商企业在物流环节的成本控制&#xff0c;直接影响着整体运营效率和利润空间。作为国内主流的物流数据服务商&#xff0c;快递鸟API接口凭借其聚合查询、电子面单、轨迹跟踪等功能&#xff0c;成为众多电商企业的选择。但如何精准解析其收费模式&#xff0c;并制定科学的成…

maven 最短路径依赖优先

问题描述&#xff1a; 项目在升级大版本后出现了&#xff0c;两个不同模块所引用的同一个依赖包版本不同 module A 引用了 module B&#xff0c;module B 引用了 A_1.0.jar->B_1.0.jar->C_1.0.jar(C 为B 里面的包) 在执行 mvn dependency:tree 后发现&#xff1a; modul…

游戏引擎学习第314天:将精灵拆分成多个层

回顾并为今天的工作做准备 我们今天继续昨天开始的工作&#xff0c;现在我们要回到渲染中处理 Z 值的最终环节。我们目前已经有一个我们认为还算合理的排序方式&#xff0c;虽然可能还需要在接下来的过程中进行一些调整&#xff0c;但总体上已经有了一个明确的方向。 我们已经…

HashSet的基本概念

ashSet的基本概念 - HashSet 是C#中用于存储唯一元素的泛型集合类&#xff0c;它基于哈希表实现&#xff0c;具有快速查找、添加和删除元素的特性。 - 核心特点&#xff1a; - 不允许存储重复元素 - 元素无序排列 - 查找、添加、删除操作的平均时间复杂度为O(1) - 实现了 IEnum…