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

手写tomcat:基本功能实现(4)

逻辑架构

 

  1. HTTP 请求与 Socket

    • 左侧的 “HTTP 请求” 箭头指向 “socket”,表示客户端发送的 HTTP 请求通过 socket 传输到服务器。Socket 负责接收请求,并提取出其中的 请求路径(如 /first)和 请求方法(如 GET、POST),为后续处理做准备。
  2. Servlet 容器的路由机制

    • 图中粉色表格代表 Servlet 容器内的路由映射表,每一行记录了一个 URL 路径与对应 Servlet 对象的映射关系。例如,路径 /first 对应 firstServlet 对象,/second 对应 secondServlet 对象。容器根据 socket 提取的请求路径,从映射表中找到匹配的 Servlet 来处理请求。
  3. Web 应用结构(webapps)

    • webapps 是存放 Web 应用的目录,图中 myweb 是其中一个应用,包含两类资源:
      • Servlet 资源:动态处理请求的 Servlet 程序。
      • 静态资源:如 HTML、CSS、图片等无需动态处理的文件。
  4. 核心类与注解支持

    • 右侧蓝色区域包含 HttpServlet 类、HttpRequest 和 HttpResponse,它们是处理请求和响应的核心类。HttpServlet 是 Servlet 的基类,HttpRequest 用于封装请求信息,HttpResponse 用于构造响应数据。
    • 紫色区域表示对 @WebServlet 注解的支持。该注解用于配置 Servlet 对应的 URL 路径等信息,简化 Servlet 的注册过程,与图中路由映射表的功能相呼应。

TomcatRoute类

package com.qcby.config;import com.qcby.Util.SearchClassUtil;
import com.qcby.servlet.Httpservlet;
import com.qcby.zj.YbyServlet;import java.util.HashMap;
import java.util.List;import java.util.List;
import java.util.Map;public class TomcatRoute {public static HashMap<String, Httpservlet> Route = new HashMap<>();static {List<String> classesPath = SearchClassUtil.searchClass();for (String path : classesPath) {try {//加载类Class clazz = Class.forName(path);//获取注解YbyServlet webServlet = (YbyServlet) clazz.getDeclaredAnnotation(YbyServlet.class);
//                对象Object servlet = clazz.getDeclaredConstructor().newInstance();Route.put(webServlet.url(), (Httpservlet) servlet);
//                Httpservlet servlet = (Httpservlet) clazz.newInstance();
//                servletMap.put(webServlet.url(),servlet);System.out.println(Route);} catch (Exception e) {e.printStackTrace();}}}}

主要功能是自动扫描带有特定注解的 Servlet 类并注册到路由表中。使用静态 HashMap 存储路径到 Servlet 的映射关系。加载类:Class.forName("com.qcby.servlet.HomeServlet")。

一、核心功能与设计思想

public class TomcatRoute {public static HashMap<String, Httpservlet> Route = new HashMap<>();static { ... }
}

功能:自动扫描并注册所有带有YbyServlet注解的 Servlet 类

设计思想

  • 基于 "约定优于配置" 原则,通过注解简化 Servlet 注册
  • 使用静态代码块确保在类加载时完成初始化
  • 采用单例模式管理 Servlet 实例(每个 Servlet 只有一个实例)

二、核心组件详解

1. 路由注册表

public static HashMap<String, Httpservlet> Route = new HashMap<>();
  • 数据结构:静态 HashMap 存储路径到 Servlet 的映射
  • :URL 路径(如/user),来自YbyServlet注解的url()属性
  • :实现了Httpservlet接口的 Servlet 实例

2. 类扫描机制

List<String> classesPath = SearchClassUtil.searchClass();
  • SearchClassUtil功能
    • 扫描指定包下的所有类
    • 返回类的全限定名列表(如["com.qcby.servlet.UserServlet", "com.qcby.servlet.OrderServlet"]
  • 实现方式
    • 使用类加载器获取资源路径
    • 递归遍历所有.class文件
    • 将文件路径转换为类的全限定名

HttpServletResponse类

package com.qcby.Response;import com.qcby.Request.HttpServletRequest;import java.io.IOException;
import java.io.OutputStream;public class HttpServletResponse {private OutputStream outputStream;public HttpServletResponse(OutputStream outputStream){this.outputStream = outputStream;}public  void writeServlet(String context) throws IOException {outputStream.write(context.getBytes());}
}

这段代码实现了 HTTP 响应的基础功能,负责将服务器处理结果返回给客户端

Tomcat

package com.qcby;
//tomcat主启动类
import com.qcby.config.TomcatRoute;
import com.qcby.servlet.Httpservlet;
import com.qcby.Request.HttpServletRequest;
import com.qcby.Response.HttpServletResponse;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;public class Mytomcat {static HashMap<String,Httpservlet> routes= TomcatRoute.Route;public  static void dispatch(HttpServletRequest request,HttpServletResponse response) throws IOException {Httpservlet servlet=routes.get(request.getPath());if(servlet!=null){servlet.service(request,response);}}public static void main(String[] args) {try {System.out.append("服务器启动......");
//				1.定义ServerSocket对象进行服务器的端口注册ServerSocket serverSocket = new ServerSocket(8080);while (true) {
//				2.监听客户端的socket链接程序Socket socket = serverSocket.accept();//阻塞监听
//				3.从socket对象当中获得一个字节流对象InputStream iStream = socket.getInputStream();HttpServletRequest request=new HttpServletRequest();BufferedReader reader=new BufferedReader(new InputStreamReader(iStream));String str=reader.readLine();request.setMethod(str.split("\\s")[0]);request.setPath(str.split("\\s")[1]);System.out.println(request.getMethod() + " " + request.getPath());OutputStream outputStream=socket.getOutputStream();HttpServletResponse response=new HttpServletResponse(outputStream);dispatch(request,response);}} catch(Exception e){e.printStackTrace();}}}

 

相关文章:

  • 轻量、优雅、高扩展的事件驱动框架——Hibiscus-Signal
  • Git 版本控制系统入门指南
  • 我的世界模组开发——特征(2)
  • 使用 Vue Tour 封装一个统一的页面引导组件
  • Typescript学习教程,从入门到精通,TypeScript 函数语法知识点及案例代码(5)
  • 六、绘制图片
  • Golang 范型
  • C# WPF .NET Core和.NET5之后引用System.Windows.Forms的解决方案
  • 数据库——SQL约束窗口函数介绍
  • 量化用到的机器学习书籍推荐
  • 广和通L610模块通过AT指令访问服务器方案:嵌赛使用
  • QT6 源(105)篇二:阅读与注释 QAction,给出源代码
  • RJ连接器的未来:它还会是网络连接的主流标准吗?
  • Java-Objects类高效应用的全面指南
  • Vue百日学习计划Day19-20天详细计划-Gemini版
  • 从数据分析到数据可视化:揭开数据背后的故事
  • ArrayList-集合使用
  • 【C语言练习】046. 编写插入排序算法
  • 编译原理实验五:LR语法分析器的控制程序
  • BrepGen中的几何特征组装与文件保存详解 deepwiki occwl OCC包装库
  • 网站和虚拟服务器/营销网站建设免费
  • 如何找网站制作/软文世界平台
  • 做服务网站/百度发视频步骤
  • 网站 英语/百度怎么发帖子
  • 临沂网站建设选盛誉/福州seo网址优化公司
  • 定制开发一个网站多少钱/旅游企业seo官网分析报告