手寫tomcat

package com.qcby.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)// 表示該注解只能用于類上
@Retention(RetentionPolicy.RUNTIME)// 表示該注解在運行時存在
public @interface ZFLServlet {String url()default "";
}

package com.qcby.config;import com.qcby.annotation.ZFLServlet;
import com.qcby.servlet.HttpServlet;
import com.qcby.util.SearchClassUtil;import java.util.HashMap;
import java.util.List;public class TomcatRoute {public static HashMap<String, HttpServlet> routes = new HashMap<>();static {List<String> paths = SearchClassUtil.searchClass();//獲取全路徑名//根據全路徑生成對象for (String path : paths) {try {Class clazz = Class.forName(path);//生成類對象ZFLServlet webServlet = (ZFLServlet) clazz.getDeclaredAnnotation(ZFLServlet.class);System.out.println(webServlet.url());routes.put(webServlet.url(), (HttpServlet) clazz.getDeclaredConstructor().newInstance());} catch (Exception e) {e.printStackTrace();}}}}

package com.qcby.myweb;import com.qcby.annotation.ZFLServlet;
import com.qcby.requset.HttpServletRequest;
import com.qcby.response.HttpServletResponse;
import com.qcby.servlet.HttpServlet;import java.io.IOException;@ZFLServlet(url = "/delete")
public class DeleteServlet extends HttpServlet {@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {super.doPost(request, response);}@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {super.doGet(request, response);}
}

package com.qcby.myweb;import com.qcby.annotation.ZFLServlet;
import com.qcby.requset.HttpServletRequest;
import com.qcby.response.HttpServletResponse;
import com.qcby.servlet.HttpServlet;import java.io.IOException;
@ZFLServlet(url = "/insert")
public class InsertServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) {System.out.println("我是insert......");}@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {super.doPost(request, response);}
}

package com.qcby.servlet;import com.qcby.requset.HttpServletRequest;
import com.qcby.response.HttpServletResponse;import java.io.IOException;public abstract class HttpServlet implements servlet{public void doPost(HttpServletRequest request, HttpServletResponse response) {}public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {}@Overridepublic void service(HttpServletRequest request, HttpServletResponse response) throws IOException {if (request.getMethod().equals("GET")){doGet(request,response);} else if (request.getMethod().equals("POST")) {doPost(request,response);}}}

package com.qcby.requset;public class HttpServletRequest {private String url;private String method;public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}
}
package com.qcby.response;import com.qcby.util.FileUtil;
import com.qcby.util.ResponseUtil;import java.io.File;
import java.io.IOException;
import java.io.OutputStream;public class HttpServletResponse {//輸出流private OutputStream outputStream;public HttpServletResponse(OutputStream outputStream) {this.outputStream = outputStream;}/*** 返回動態資源* @param context*/public void write(String context) throws IOException {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());}}
}

package com.qcby.servlet;import com.qcby.requset.HttpServletRequest;
import com.qcby.response.HttpServletResponse;import java.io.IOException;public abstract class HttpServlet implements servlet{public void doPost(HttpServletRequest request, HttpServletResponse response) {}public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {}@Overridepublic void service(HttpServletRequest request, HttpServletResponse response) throws IOException {if (request.getMethod().equals("GET")){doGet(request,response);} else if (request.getMethod().equals("POST")) {doPost(request,response);}}}
package com.qcby.servlet;import com.qcby.requset.HttpServletRequest;
import com.qcby.response.HttpServletResponse;import java.io.IOException;public interface servlet {public void service(HttpServletRequest request, HttpServletResponse response) throws IOException;
}

package com.qcby.util;import java.io.*;public class FileUtil {public  static  boolean witeFile(InputStream inputStream, OutputStream outputStream){boolean success = false ;BufferedInputStream bufferedInputStream ;BufferedOutputStream bufferedOutputStream;try {bufferedInputStream = new BufferedInputStream(inputStream);bufferedOutputStream = new BufferedOutputStream(outputStream);bufferedOutputStream.write(ResponseUtil.responseHeader200.getBytes());int count = 0;while (count == 0){count = inputStream.available();}int fileSize = inputStream.available();long written = 0;int beteSize = 1024;byte[] bytes = new byte[beteSize];while (written < fileSize){if(written + beteSize > fileSize){beteSize = (int)(fileSize - written);bytes = new byte[beteSize];}bufferedInputStream.read(bytes);bufferedOutputStream.write(bytes);bufferedOutputStream.flush();written += beteSize;}success = true;} catch (IOException e) {e.printStackTrace();}return success;}public static boolean writeFile(File file,OutputStream outputStream) throws Exception{return witeFile(new FileInputStream(file),outputStream);}public static String getResoucePath(String path){String resource = FileUtil.class.getResource("/").getPath();return resource + "\\" + path;}
}

package com.qcby.util;/*** 設置響應頭*/
public class ResponseUtil {public  static  final String responseHeader200 = "HTTP/1.1 200 \r\n"+"Content-Type:text/html\r\n"+"\r\n";public static String getResponseHeader404(){return "HTTP/1.1 404 \r\n"+"Content-Type:text/html\r\n"+"\r\n" + "404";}public static String getResponseHeader200(String context){return "HTTP/1.1 200\r\n"+"Content-Type:text/html\r\n"+"\r\n" + context;}}

package com.qcby.util;import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;public class SearchClassUtil {public static List<String> classPaths = new ArrayList<>();public static List<String> searchClass() {// 需要掃描的包名String basePack = "com.qcby.myweb";try {// 使用字符串替換Enumeration<URL> resources = SearchClassUtil.class.getClassLoader().getResources(basePack.replace(".", "/"));while (resources.hasMoreElements()) {URL url = resources.nextElement();String protocol = url.getProtocol();if ("file".equals(protocol)) {String filePath = URLDecoder.decode(url.getFile(), "UTF-8");doPath(new File(filePath), basePack);} else if ("jar".equals(protocol)) {// 處理JAR包情況System.out.println("暫未完整處理JAR包情況");}}} catch (IOException e) {e.printStackTrace();}return classPaths;}/*** 該方法會得到所有的類,將類的絕對路徑寫入到classPaths中** @param file 當前文件或目錄* @param basePack 基礎包名*/private static void doPath(File file, String basePack) {if (file.isDirectory()) {File[] files = file.listFiles();if (files != null) {for (File subFile : files) {doPath(subFile, basePack);}}} else if (file.getName().endsWith(".class")) {String classFilePath = file.getAbsolutePath();// 使用字符串替換classFilePath = classFilePath.substring(classFilePath.indexOf(basePack.replace(".", File.separator)));classFilePath = classFilePath.replace(File.separator, ".");classFilePath = classFilePath.substring(0, classFilePath.length() - 6);classPaths.add(classFilePath);}}public static void main(String[] args) {List<String> paths = searchClass();for (String path : paths) {System.out.println(path);}}
}

package com.qcby;import com.qcby.config.TomcatRoute;
import com.qcby.requset.HttpServletRequest;
import com.qcby.response.HttpServletResponse;
import com.qcby.servlet.HttpServlet;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;public class MyTomcat {static HashMap<String, HttpServlet> routes = TomcatRoute.routes; //tomcat路由\/*** 分發器*/public  void dispatch(HttpServletRequest request ,HttpServletResponse response) throws IOException {HttpServlet servlet = routes.get(request.getUrl());  //if(servlet!=null){ //說明請求的就是我們的servletservlet.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);}}//socketpublic static void main(String[] args) throws IOException {MyTomcat myTomcat = new MyTomcat();myTomcat.start();}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89633.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89633.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89633.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android平臺下openssl動態庫編譯

1. 下載Linux平臺下的NDK軟件包 NDK 下載 | Android NDK | Android Developers 下載完成后執行解壓命令 # unzip android-ndk-r27d-linux.zip 2. 下載openssl-1.1.1w源碼包&#xff0c;并解壓 # tar -xzvf openssl-1.1.1w.tar.gz 3. 進入解壓后的openssl-1.1.1w目錄 …

【C++基礎】面試高頻考點解析:extern “C“ 的鏈接陷阱與真題實戰

名稱修飾&#xff08;Name Mangling&#xff09;是C為支持重載付出的代價&#xff0c;而extern "C"則是跨越語言邊界的橋梁——但橋上的陷阱比橋本身更值得警惕 一、extern "C" 的核心概念與高頻考點1.1 鏈接規范與名字改編機制C 為支持函數重載&#xff0…

OpenCV 官翻 4 - 相機標定與三維重建

文章目錄相機標定目標基礎原理代碼配置校準去畸變1、使用 cv.undistort()2、使用**重映射**方法重投影誤差練習姿態估計目標基礎渲染立方體極線幾何目標基礎概念代碼練習從立體圖像生成深度圖目標基礎概念代碼附加資源練習相機標定 https://docs.opencv.org/4.x/dc/dbb/tutori…

Python類中方法種類與修飾符詳解:從基礎到實戰

文章目錄Python類中方法種類與修飾符詳解&#xff1a;從基礎到實戰一、方法類型總覽二、各類方法詳解1. 實例方法 (Instance Method)2. 類方法 (Class Method)3. 靜態方法 (Static Method)4. 抽象方法 (Abstract Method)5. 魔術方法 (Magic Method)三、方法修飾符對比表四、綜合…

VSCode使用Jupyter完整指南配置機器學習環境

接下來開始機器學習部分 第一步配置環境&#xff1a; VSCode使用Jupyter完整指南 1. 安裝必要的擴展 打開VSCode&#xff0c;按 CtrlShiftX 打開擴展市場&#xff0c;搜索并安裝以下擴展&#xff1a; 必裝擴展&#xff1a; Python (Microsoft官方) - Python語言支持Jupyter (Mi…

數據結構與算法之美:拓撲排序

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《C修煉之路》、《Linux修煉&#xff1a;終端之內 洞悉真理…

Ubuntu18.04 系統重裝記錄

Ubuntu18.04 系統重裝記錄 1 安裝google拼音 https://blog.csdn.net/weixin_44647619/article/details/144720947 你好&#xff01; 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章&#xff0c;了解一下Markdo…

Maven常用知識總結

Maven常用知識總結Maven 安裝與配置windows mvn安裝與配置IntelliJ IDEA 配置IntelliJ IDEA 配置系統mavenIntellij IDEA Maven使用IntelliJ IDEA 不能運行項目常見問題pom.xml 常用標簽講解parentgroupId artifactId versiondependencypropertiespluginpackagingdependencyMan…

PHP框架在大規模分布式系統的適用性如何?

曾幾何時&#xff0c;PHP被貼上“只適合小網站”的標簽。但在技術飛速發展的今天&#xff0c;PHP框架&#xff08;如Laravel、Symfony、Hyperf、Swoft等&#xff09; 早已脫胎換骨&#xff0c;勇敢地闖入了大規模分布式系統的疆域。今天&#xff0c;我們就來聊聊它的真實戰斗力…

DC-DC降壓轉換5.5V/3A高效率低靜態同步降壓轉換具有自適應關斷功能

概述&#xff1a;PC1032是一款高效且體積小巧的同步降壓轉換器&#xff0c;適用于低輸入電壓應用。它是緊湊設計的理想解決方案。其2.5V至5.5V的輸入電壓范圍適用于幾乎所有電池供電的應用。在中等至重負載范圍內&#xff0c;它以1.5MHz&#xff08;典型值&#xff09;的PWM模式…

min_25篩學習筆記+牛客多校02E

本來沒有學習這種較難的算法的想法的&#xff0c;因為比賽也做不到這種難度的題&#xff0c; 但是最近打牛客多校02&#xff0c;有一題要求 [1,n][1,n][1,n] 中素數的個數&#xff0c;我以為是像莫反一樣容斥&#xff0c;但是后面感覺不行。賽后知道是用 min_25 篩來求&#xf…

FunASR Paraformer-zh:高效中文端到端語音識別方案全解

項目簡介 FunASR 是阿里巴巴達摩院開源的端到端語音識別工具箱,集成了多種語音識別、語音活動檢測(VAD)、說話人識別等模塊。其中 paraformer-zh 和 paraformer-zh-streaming 是針對中文語音識別任務優化的端到端模型,分別適用于離線和流式場景。Paraformer 采用并行 Tran…

數據結構自學Day9: 二叉樹的遍歷

一、二叉樹的遍歷“遍歷”就是按某種規則 依次訪問樹中的每個節點&#xff0c;確保 每個節點都被訪問一次且只訪問一次遍歷&#xff1a;前序 中序 后序&#xff08;深度優先&#xff09;&#xff0c;層序&#xff08;廣度優先&#xff09;類型遍歷方法特點深度優先遍歷前序、中…

Leetcode(7.16)

求二叉樹最小深度class Solution {public int minDepth(TreeNode root) {if (root null) {return 0;}Queue<TreeNode> queue new LinkedList<>();queue.offer(root);int depth 0;while (!queue.isEmpty()) {depth;int levelSize queue.size();for (int i 0; i…

Go從入門到精通(25) - 一個簡單web項目-實現鏈路跟蹤

Go從入門到精通(25) 一個簡單web項目-實現鏈路跟蹤 文章目錄Go從入門到精通(25)前言為什么需要分布式鏈路跟蹤&#xff1f;go實現鏈路跟蹤搭建zipkin 服務安裝依賴添加tracing包&#xff0c;OpenTelemetry 和Zipkin在 Gin 中集成 OpenTelemetry 中間件log包添加獲取traceId方法…

2025年最新秋招java后端面試八股文+場景題

一、Java核心八股文&#xff08;2025年最新版&#xff09;1. Java基礎HashMap vs ConcurrentHashMapHashMap&#xff1a;非線程安全&#xff0c;JDK1.8后采用數組鏈表/紅黑樹&#xff0c;擴容時可能死循環&#xff08;JDK1.7&#xff09;。ConcurrentHashMap&#xff1a;JDK1.8…

esp32 sd卡

ref&#xff1a; platform io & arduino Boards — PlatformIO latest documentation https://github.com/espressif/arduino-esp32/blob/master/libraries/SD_MMC/README.md SD 卡實驗 | 極客俠GeeksMan GitHub - fabianoriccardi/ESPLogger: An Arduino library pro…

Java學習--------消息隊列的重復消費、消失與順序性的深度解析?

在 Java 分布式系統開發中&#xff0c;消息隊列的應用已十分普遍。但隨著業務規模擴大&#xff0c;消息的重復消費、意外消失、順序錯亂等問題逐漸成為系統穩定性的隱患。本文將從 Java 開發者的視角&#xff0c;深入分析這三大問題的產生原因、業務后果&#xff0c;并結合具體…

【Oracle】centos7離線靜默安裝oracle11g(p13390677_112040)

博文地址&#xff1a;https://blog.csdn.net/gitblog_06670/article/details/142569814 倉庫地址&#xff1a;https://gitcode.com/Open-source-documentation-tutorial/31eb1/?utm_sourcedocument_gitcode&indexbottom&typecard 參考安裝地址&#xff1a; 收費版&…

智能設備暢想

### 智能設備暢想 突然想到了一個好主意 因為最近在查無人機的相關資料&#xff08;很早之前就想搞個無人機玩玩但始終沒有買&#xff09; 在了解自組裝方面的內容時&#xff0c;和AI溝通了下 正好之前組裝的 小智AI 基本上已經完善了&#xff0c;也正在考慮其在其他方向拓展的…