qidao123.com技术社区-IT企服评测·应用市场

标题: 手写tomcat:根本功能实现(3) [打印本页]

作者: 傲渊山岳    时间: 前天 00:18
标题: 手写tomcat:根本功能实现(3)
 TomcatRoute类

TomcatRoute类是Servlet容器,是Tomcat中最核心的部分,其自己是一个HashMap,其功能为:将路径和对象写入Servlet容器中。
  1. package com.qcby.config;
  2. import com.qcby.Util.SearchClassUtil;
  3. import com.qcby.servlet.Httpservlet;
  4. import com.qcby.zj.YbyServlet;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.List;
  8. import java.util.Map;
  9. public class TomcatRoute {
  10.     public static HashMap<String, Httpservlet> Route = new HashMap<>();
  11.         static {
  12.             List<String> classesPath = SearchClassUtil.searchClass();
  13.             for (String path : classesPath) {
  14.                 try {
  15.                     //加载类
  16.                     Class clazz = Class.forName(path);
  17.                     //获取注解
  18.                     YbyServlet webServlet = (YbyServlet) clazz.getDeclaredAnnotation(YbyServlet.class);
  19. //                对象
  20.                     Object servlet = clazz.getDeclaredConstructor().newInstance();
  21.                     Route.put(webServlet.url(), (Httpservlet) servlet);
  22. //                Httpservlet servlet = (Httpservlet) clazz.newInstance();
  23. //                servletMap.put(webServlet.url(),servlet);
  24.                     System.out.println(Route);
  25.                 } catch (Exception e) {
  26.                     e.printStackTrace();
  27.                 }
  28.             }
  29.         }
  30. }
复制代码
 静态代码块 

1. 确保初始化时机

静态代码块在类加载时自动执行,且仅执行一次。这确保了路由表在程序启动时就被初始化,后续无需手动调用初始化方法。
对比其他初始化方式


2. 全局唯一性

静态代码块属于类,而非某个实例。无论创建多少个TomcatRoute对象,路由表只会初始化一次。
功能


public static HashMap<String, Httpservlet> Route = new HashMap<>();

1. 多态性的应用

Httpservlet是所有具体 Servlet 的抽象父类(或接口),通过父类范例引用子类实例,可以实现统一调用
2. 解耦路由逻辑与具体实现

路由系统只需关注哀求路径与处置惩罚逻辑的映射关系,而无需关心具体 Servlet 的实现细节。
3. 统一接口界说

Httpservlet通常界说了处置惩罚哀求的标准方法(如service()、doGet()、doPost()),所有子类必须实现这些方法。
4. 符合 Servlet 规范

在标准 Java Web 开辟中,所有 Servlet 都必须实现javax.servlet.Servlet接口(或继续HttpServlet)。这种设计模仿了标准 Servlet 容器的工作原理。
MyTomcat

  1. package com.qcby;
  2. //tomcat主启动类
  3. import com.qcby.config.TomcatRoute;
  4. import com.qcby.servlet.Httpservlet;
  5. import com.qcby.Request.HttpServletRequest;
  6. import com.qcby.Response.HttpServletResponse;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import java.net.ServerSocket;
  10. import java.net.Socket;
  11. import java.util.HashMap;
  12. public class Mytomcat {
  13.     static HashMap<String,Httpservlet> routes= TomcatRoute.Route;
  14.     static  HttpServletRequest request=new HttpServletRequest();
  15.    static  HttpServletResponse response=new HttpServletResponse();
  16.     public  static void dispatch(){
  17.         Httpservlet servlet=routes.get(request.getPath());
  18.         if(servlet!=null){
  19.             servlet.service(request,response);
  20.         }
  21.     }
  22.     public static void main(String[] args) {
  23.         try {
  24.             System.out.append("服务器启动......");
  25. //                                1.定义ServerSocket对象进行服务器的端口注册
  26.             ServerSocket serverSocket = new ServerSocket(8080);
  27.             while (true) {
  28. //                                2.监听客户端的socket链接程序
  29.                 Socket socket = serverSocket.accept();//阻塞监听
  30. //                                3.从socket对象当中获得一个字节流对象
  31.                 InputStream iStream = socket.getInputStream();
  32. //                                打印输出
  33.                 int len = 0;
  34.                 int ReviceLen = 0;
  35. //                        计算机网络数据是以8bit为一个单元进行发送,我们接收到发送方发生的byte数据
  36. //                                将其转化为utf-8格式输出
  37.                 byte[] recvBuf = new byte[1024];
  38.                 while ((ReviceLen = iStream.read(recvBuf)) != -1) {
  39.                     String count=new String(recvBuf,0,ReviceLen,"UTF-8");
  40.                     String method=count.split(" ")[0];
  41.                     String url=count.split(" ")[1];
  42.                     request.setMethod(method);
  43.                     request.setPath(url);
  44.                 }
  45.                 dispatch();
  46.             }
  47.             } catch(Exception e){
  48.                 // TODO: handle exception
  49.             }
  50.         }
  51. }
复制代码
1. 团体架构

这个浅易服务器包含三个核心组件:

2. 核心成员变量 

  1. static HashMap<String,Httpservlet> routes = TomcatRoute.Route;
  2. static HttpServletRequest request = new HttpServletRequest();
  3. static HttpServletResponse response = new HttpServletResponse();
复制代码

 3. 哀求分发逻辑

  1. public static void dispatch() {
  2.     Httpservlet servlet = routes.get(request.getPath());
  3.     if (servlet != null) {
  4.         servlet.service(request, response);
  5.     }
  6. }
复制代码

4. 主服务器逻辑

  1. public static void main(String[] args) {
  2.     try {
  3.         System.out.println("服务器启动......");
  4.         ServerSocket serverSocket = new ServerSocket(8080);
  5.         
  6.         while (true) {
  7.             // 1. 监听客户端连接(阻塞)
  8.             Socket socket = serverSocket.accept();
  9.             InputStream iStream = socket.getInputStream();
  10.             
  11.             // 2. 解析HTTP请求
  12.             byte[] recvBuf = new byte[1024];
  13.             int ReviceLen = iStream.read(recvBuf);
  14.             String count = new String(recvBuf, 0, ReviceLen, "UTF-8");
  15.             String method = count.split(" ")[0];
  16.             String url = count.split(" ")[1];
  17.             
  18.             // 3. 设置请求信息
  19.             request.setMethod(method);
  20.             request.setPath(url);
  21.             
  22.             // 4. 分发请求
  23.             dispatch();
  24.         }
  25.     } catch (Exception e) {
  26.         e.printStackTrace();
  27.     }
  28. }
复制代码
关键步调


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4