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

手写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.dtcms.com/a/288857.html

相关文章:

  • JAVA学习-练习试用Java实现“贝叶斯网络:实现一个简单的贝叶斯网络用于因果推理”
  • Transient Storage
  • Redis通用常见命令(含面试题)
  • [硬件电路-51]:晶体管既可以用于模拟电路芯片,也可以用于数字电路芯片,晶体管应用在这两个领域的相同点和本质区别?
  • Linux之dpkg--命令的用法
  • Apache基础配置
  • DOM型XSS破坏
  • gcc 和 g++ 的区别
  • Pycaita二次开发基础代码解析:材料属性管理与焊点坐标导出实战指南
  • Go实现用户登录小程序
  • WPF学习笔记(28)Interaction.Triggers的意义与使用方式
  • Java设计模式之行为型模式(备忘录模式)应用场景分析
  • HTML和CSS快速入门
  • 【算法】二分查找经典例题
  • 2025最新 PostgreSQL17 安装及配置(Windows原生版)
  • 大语言模型调用方式与函数调用
  • Node.js 与 Java 性能对比
  • 零基础 “入坑” Java--- 十三、再谈类和接口
  • 网络原理——IP
  • 【硬件】GalaxyTabPro10.1(SM-T520)刷机/TWRP/LineageOS14/安卓7升级小白向保姆教程
  • Nginx的location匹配规则
  • 【数据结构与算法】数据结构初阶:详解二叉树(一)
  • Mysql 学习总结(90)—— Mysql 8.0 25 条性能优化实战指南
  • ubuntu 24.04 xfce4 钉钉输入抢焦点问题
  • Baumer工业相机堡盟工业相机如何通过YoloV8的深度学习模型实现螺母螺丝的分类检测(C#代码,UI界面版)
  • 二、Spark 开发环境搭建 IDEA + Maven 及 WordCount 案例实战
  • PaddleOCR 与 PaddleX 调试
  • linux ps -a与-e的区别
  • Spring Cloud Gateway高危隐患
  • 社交圈子系统开源社交源码 / 小程序+H5+APP 多端互通的底层技术分析