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

手写Tomcat代码整理(自用)

一、配置Maven环境

新建项目需要加载,等右下方的进度条满就行。

在D盘根目录上解压apache-maven-3.6.2-zip

同时在D盘根目录新建文件夹Maven

二、手写Tomcat

1、ServletConfigMapping

package com.qcby.config; import com.qcby.lib.HttpServlet; import com.qcby.lib.WebServlet; import com.qcby.utils.SearchClassUtil; import java.util.HashMap; import java.util.List; import java.util.Map; /** * servlet容器配置类 */ public class ServletConfigMapping { /** * <String, HttpServlet> * String:路径作为key值 * HttpServlet:servlet对象作为value值 (多态:向上转型----->父类引用指向子类对象) * */ public static Map<String, HttpServlet> classMapping = new HashMap<>(); //servlet容器 //特点:在main方法执行之前执行,以修饰main方法 static { List<String> paths = SearchClassUtil.searchClass( "com.qcby.webapps.myweb"); for (String path: paths) { // 获取类的注解信息,并将path作为key值,将对象作为value值 存放如classMapping当中 try{ Class clazz =Class.forName(path); //获取类对象 //获取类的注解信息 WebServlet webServlet =(WebServlet) clazz.getDeclaredAnnotation(WebServlet.class); //System.out.println(webServlet.value()); HttpServlet servlet = (HttpServlet) clazz.getDeclaredConstructor().newInstance(); classMapping.put(webServlet.value(),servlet); }catch (Exception e){ e.printStackTrace(); } } } public static void main(String[] args) { } }

2、GenericServlet

package com.qcby.lib; import java.io.IOException; public abstract class GenericServlet implements Servlet{ @Override public void init() { } public abstract void service(ServletRequest request, ServletResponse response) throws IOException; @Override public void destroy() { } }

3、HttpServlet

package com.qcby.lib; import java.io.IOException; public abstract class HttpServlet extends GenericServlet{ public abstract void doGet(ServletRequest request, ServletResponse response) throws IOException; public abstract void doPost(ServletRequest request, ServletResponse response); @Override public void service(ServletRequest request, ServletResponse response) throws IOException { if(request.getMethod().equals("GET")){ doGet(request,response); }else if(request.getMethod().equals("POST")){ doPost(request,response); } } }

4、HttpServletRequest

package com.qcby.lib; public class HttpServletRequest implements ServletRequest{ private String method; private String path; @Override public String getMethod() { return method; } @Override public String getPath() { return path; } @Override public String setMethod(String method) { return this.method = method ; } @Override public String setPath(String path) { return this.path = path; } }

5、HttpServletResponse

package com.qcby.lib; import com.qcby.utils.FileUtil; import java.io.File; import java.io.IOException; import java.io.OutputStream; public class HttpServletResponse implements ServletResponse{ //获取输出流 private OutputStream outputStream; public OutputStream getOutputStream() { return outputStream; } public void setOutputStream(OutputStream outputStream) { this.outputStream = outputStream; } /** * 动态资源数据写回 * @param context * @throws IOException */ public void append(String context) throws IOException { outputStream.write(context.getBytes()); } /** * 返回静态资源 * @param path 静态资源文件的相对路径 * @throws Exception */ public void returnStatic(String path) throws Exception { String resource = FileUtil.getResourcePath(path); // 获取静态资源真实路径 File file = new File(resource); // 静态文件 if(file.exists()){ //静态文件存在 FileUtil.writeFile(file,outputStream); }else { System.out.println("404静态资源文本不存在......"); } } }

6、Servlet

package com.qcby.lib; import java.io.IOException; public interface Servlet { public void init(); public void service(ServletRequest request,ServletResponse response) throws IOException; public void destroy(); }

7、ServletRequest

package com.qcby.lib; public interface ServletRequest { String getMethod(); String getPath(); String setMethod(String method); String setPath(String path); }

8、ServletResponse

package com.qcby.lib; import java.io.IOException; public interface ServletResponse { public void append(String context)throws IOException; }

9、WebServlet

package com.qcby.lib; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) //生命周期 @Target(ElementType.TYPE) //作用范围 public @interface WebServlet { String value(); }

10、MyFirstServlet

package com.qcby.webapps.myweb; import com.qcby.lib.HttpServlet; import com.qcby.lib.ServletRequest; import com.qcby.lib.ServletResponse; import com.qcby.lib.WebServlet; import com.qcby.utils.ResponseUtil; import java.io.IOException; @WebServlet("/first") public class MyFirstServlet extends HttpServlet { @Override public void doGet(ServletRequest request, ServletResponse response) throws IOException { System.out.println("MyFirstServlet doGet 这里的地址"); response.append(ResponseUtil.getResponseHeader200("<h1>这是第一个Servlet</h1>")); } @Override public void doPost(ServletRequest request,ServletResponse response){ } }

11、MySecondServlet

package com.qcby.webapps.myweb; import com.qcby.lib.HttpServlet; import com.qcby.lib.ServletRequest; import com.qcby.lib.ServletResponse; import com.qcby.lib.WebServlet; import com.qcby.utils.ResponseUtil; import java.io.IOException; /** * 1.继承HttpServlet * 2.重写doGet()和doPost()方法 省略 * 3.@WebServlet("/MySecondServlet") 配置访问路径 */ @WebServlet("/second") public class MySecondServlet extends HttpServlet { @Override public void doGet(ServletRequest request, ServletResponse response) throws IOException { System.out.println("MySecondServlet doGet 这里的地址"); response.append(ResponseUtil.getResponseHeader200( "<h1>SecondServlet</h1>")); } @Override public void doPost(ServletRequest request, ServletResponse response) { } }

12、MyTomcat

package com.qcby; import com.qcby.config.ServletConfigMapping; import com.qcby.lib.*; import com.qcby.utils.ResponseUtil; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class MyTomcat { private static HttpServletRequest httpServletRequest = new HttpServletRequest(); private static HttpServletResponse httpServletResponse = new HttpServletResponse(); private static final Integer PORT = 7788; //监听的端口号 public static void start() throws Exception { ServerSocket serverSocket = new ServerSocket(PORT); while (true) { Socket socket = serverSocket.accept(); //阻塞监听 InputStream stream = socket.getInputStream();//打开输出流 httpServletResponse.setOutputStream(socket.getOutputStream()); //获取输入流 handler(stream); } } /** * 处理客户端的请求数据,并进行保持 * * @param stream * @throws IOException */ public static void handler(InputStream stream) throws Exception { int count = 0; while (count == 0) { count = stream.available(); } byte[] bytes = new byte[count]; int read = stream.read(bytes); String request = new String(bytes, 0, read); if (request.equals("")) { System.out.println("请求为null"); } else { String firstLine = request.split("\n")[0]; String method = firstLine.split("\\s")[0]; // 请求方式(原代码存在变量名大小写错误:firstline → firstLine) String path = firstLine.split("\\s")[1]; // 请求路径(同变量名错误) System.out.println("请求方式:" + method + " " + "请求路径:" + path); httpServletRequest.setMethod(method); httpServletRequest.setPath(path); if (path.equals("")) { System.out.println("请求路径为空"); httpServletResponse.append(ResponseUtil.responseHeader404); } else if (ServletConfigMapping.classMapping.get(path) != null) { // 虽然是用HttpServlet对象进行接受,但是实际上我们返回的是MyFirstServlet/MySecondServlet/...... // HttpServlet 实际上是向上转型的产物 HttpServlet servlet = ServletConfigMapping.classMapping.get(path); servlet.service(httpServletRequest, httpServletResponse); } else { httpServletResponse.returnStatic(path); } } } //tomcat启动器 public static void main(String[] args) throws Exception { start(); } }

13、index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>hello world</h1> <h1>中文测试</h1> </body> </html>
http://www.cnnetsun.cn/news/1254.html

相关文章:

  • 雷科电力-REKE920S涂层测厚仪
  • 相机选型学习
  • 华为-AI智算网络学习-4 运维与监控实例
  • 华为-AI智算网络学习-3 fabriclnsight 监控运维平台
  • ABAP Console Reloaded:ADT 控制台与 CL_DEMO_OUTPUT 的合体进化
  • ABAP Platform 2021 让泛型与动态编程焕然一新:用新表达式告别 FIELD-SYMBOL 的年代感
  • 把 Client 当成 ABAP 系统的多租户底座:从 sy-mandt 到 CDS_CLIENT 的隔离机制与工程实践
  • CL_DEMO_OUTPUT 重新焕发活力:从 ABAP 7.56 SP01 起,把深层结构与对象实例一次性讲清楚、展示漂亮
  • 把 MANDT 锁进保险箱:ABAP Client Handling 与 Client Isolation(聚焦 AMDP 的 Client Safety )
  • 把租户关进自己的房间:ABAP Client Handling 与 Client Isolation(聚焦 CDS Table Function 与 AMDP)
  • 把客户端隔离讲透:ABAP 里的 Client Handling 从 ABAP SQL、CDS_CLIENT 到 Native SQL 风险控制
  • 别再在 HANA 里直查 CDS 了:ABAP-Managed Database Objects 与正确访问姿势全解
  • 从 F1 到 help.sap.com:ABAP 关键字文档迁移背后的门道与团队落地指南
  • 关于 SAP Fiori Frontend Server 从 standalone 到 embedded 模式的迁移之路
  • 人工智能模型组同学们的建议
  • “走马观碑”开源仓库
  • Docker中安装软件汇总(留存版)
  • StickerBaker零代码AI贴纸生成器快速部署指南
  • Step1X-Edit技术深度解析:智能图像编辑的推理革命
  • 5分钟零配置部署:QuickJS在工业边缘计算的完整实践指南
  • SegEarth-OV3: Exploring SAM 3 for Open-Vocabulary Semantic Segmentation in Remote Sensing Images
  • SAM 3: Segment Anything with Concepts
  • Docker实战指南:MySQL、Redis与C++环境的深度容器化部署
  • bat 批处理文件中 PowerShell 命令换行问题
  • java注解和反射(5)
  • 标签体系设计原理
  • SolidWorks结构建模设计方法介绍
  • SolidWorks设计树与结构设计原理
  • SolidWorks设计树深度介绍与应用
  • 当开发者遇上AI副驾驶:效率翻倍还是技能退化?