当前位置: 首页 > news >正文

手写Tomcat流程笔记

一、启动服务器

ServerSocket serverSocket = new ServerSocket(PORT); while (true) { Socket socket = serverSocket.accept(); // 阻塞监听 InputStream stream = socket.getInputStream(); httpServletResponse.setOutputStream(socket.getOutputStream()); hander(stream); }
  • ServerSocket(PORT):在指定端口启动服务器

  • accept():阻塞等待客户端连接(浏览器请求)

  • InputStream/OutputStream:获取请求和返回响应

  • hander(stream):处理HTTP请求


二、解析HTTP请求

byte[] bytes = new byte[count]; int read = stream.read(bytes); String request = new String(bytes, 0, read);
  • read():读取浏览器发来的请求数据到字节数组

  • new String(bytes,0,read):把字节数组转换为字符串

  • 从第一行解析:

    String method = firstLine.split("\\s")[0]; // 请求方式 GET/POST String path = firstLine.split("\\s")[1]; // 请求路径 /index.html
  • 将请求信息存入httpServletRequest对象:

    httpServletRequest.setMethod(method); httpServletRequest.setPath(path);

三、Servlet容器配置

public static Map<String, HttpServlet> classMapping = new HashMap<>();
  • key:请求路径/index

  • value:Servlet对象

  • Map充当Servlet容器,用于路由请求到对应Servlet

静态代码块执行

static { List<String> paths = SearchClassUtil.searchClass("com.qcby.webapps.myweb"); for (String path : paths) { Class clazz = Class.forName(path); WebServlet webServlet = (WebServlet) clazz.getAnnotation(WebServlet.class); HttpServlet servlet = (HttpServlet) clazz.getDeclaredConstructor().newInstance(); classMapping.put(webServlet.value(), servlet); } }

步骤解析

  1. 扫描包:找到所有Servlet类路径

  2. 反射加载类

    Class clazz = Class.forName(path);
  3. 读取注解

    WebServlet webServlet = (WebServlet) clazz.getAnnotation(WebServlet.class);
    • JVM生成注解对象

    • webServlet.value()得到路径,例如/index

  4. 创建Servlet对象

    HttpServlet servlet = (HttpServlet) clazz.getDeclaredConstructor().newInstance();
    • 通过反射调用无参构造方法

  5. 加入容器

    classMapping.put(webServlet.value(), servlet);
    • Map里存路径 → Servlet对象的映射


四、处理请求

if (ServletConfigMapping.classMapping.get(path) != null) { HttpServlet servlet = ServletConfigMapping.classMapping.get(path); servlet.service(httpServletRequest, httpServletResponse); } else { httpServletResponse.returnStatic(path); }
  • 根据路径找到Servlet:从Map中获取对象

  • 调用service()方法:处理请求并生成响应

  • 如果不存在对应Servlet:返回静态资源或404


五、完整请求流程

浏览器请求 URL │ ▼ ServerSocket.accept() 阻塞接收 │ ▼ 读取 InputStream → 转字符串 → 解析 method & path │ ▼ 查找 classMapping Map → 获取对应 Servlet 对象 │ ▼ 执行 servlet.service(request,response) │ ▼ 将响应写入 OutputStream → 浏览器显示结果

六、关键点总结

  1. 反射 + 注解

    • 扫描Servlet类 → 获取@WebServlet路径 → 创建对象 → 存入Map

  2. Servlet容器 Map

    • URL路径 → Servlet对象,实现路由

  3. Socket IO

    • BIO阻塞式接收请求

  4. hander(stream)

    • 解析HTTP请求 → 调用对应Servlet

  5. 动态创建对象

    clazz.getDeclaredConstructor().newInstance();
    • 运行时创建对象,不需要在代码里写具体类名

http://www.jsqmd.com/news/478696/

相关文章:

  • 筹备2026体育专栏壁纸,五类素材站点的筛选逻辑与避险指南
  • AI智慧社区--实现登录认证:验证码、JWT Token与接口校验
  • 【SQL】多表关系与冷热数据(全维度知识体系)
  • 10个大数据规范性分析案例:行业最佳实践分享
  • 基于C-NCAP中CCRs工况下的前碰撞预警及纵向避撞控制策略研究
  • React Native 热更新深度解析
  • 大模型最后一步关键训练:偏好调优,让AI更懂人心
  • CTFshow————web13————WP
  • Oracle存储过程怎么写
  • Flutter 三方库 kubernetes 的鸿蒙化适配指南 - 掌上 K8s 集群管理、实时监控容器云、打造鸿蒙端 DevOps 运维旗舰应用
  • 【TypeReference<目标泛型类型>】
  • Web前端开发技术作业随笔
  • openclaw系列1:安装
  • 开发一个简单的脚手架
  • TestPilot - 智能测试用例生成工具
  • 什么是DAS分布式光纤声波传感系统?原理与应用解析
  • 大数据领域Doris在医疗科技领域的临床数据分析
  • Flutter 三方库 hotp 的鸿蒙适配指南 - 实现 RFC 4226 标准双因素认证、在 OpenHarmony 上打造极致安全的动态令牌实战
  • 汽油生产
  • 必看!AI拓客软件源头厂家哪家强?
  • Java大厂面试实录:谢飞机的搞笑面试之旅
  • Python当中ascii码与字母的相互转换
  • 深度学习之循环神经网络RNN
  • VMware安装RedHat Linux9全攻略
  • LeeCode4.寻找两个正序数组的中位数。小白都能懂。
  • JAVA基础二
  • ContentProvider与Uri权限:跨应用数据共享
  • 攻防世界 misc题心仪的公司
  • Linux:进程调度
  • 软件测试定义、目的、调试、需求概念、软件生命周期与测试流程