当前位置: 首页 > 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.xdnf.cn/news/1159651.html

相关文章:

  • API获取及调用(以豆包为例实现图像分析)
  • 用 Jetpack Compose 写 Android 的 “Hello World”
  • SSE和WebSocket区别到底是什么
  • linux shell从入门到精通(一)——为什么要学习Linux Shell
  • MongoDB多节点集群原理 -- 复制集
  • 《杜甫传》读书笔记与经典摘要(一)
  • 人工智能之数学基础:随机实验、样本空间、随机事件
  • 【算法训练营Day15】二叉树part5
  • LVS-----TUN模式配置
  • 【LeetCode刷题指南】--反转链表,链表的中间结点,合并两个有序链表
  • 【原创】微信小程序添加TDesign组件
  • tabBar设置底部菜单选项、iconfont图标(图片)库、模拟京东app的底部导航栏
  • 零基础学习性能测试第三章:执行性能测试
  • Windows CMD(命令提示符)中最常用的命令汇总和实战示例
  • 30天打牢数模基础-SVM讲解
  • Python 单例模式几种实现方式
  • Dify 1.6 安装与踩坑记录(Docker 方式)
  • ZooKeeper学习专栏(二):深入 Watch 机制与会话管理
  • 【单片机外部中断实验修改动态数码管0-99】2022-5-22
  • 大语言模型:人像摄影的“达芬奇转世”?——从算法解析到光影重塑的智能摄影革命
  • Vuex 核心知识详解:Vue2Vue3 状态管理指南
  • 【设计模式C#】享元模式(用于解决多次创建对象而导致的性能问题)
  • TypeScript 中替代 Interface 的方案
  • 17.TaskExecutor与ResourceManager交互
  • 对粒子群算法的理解与实例详解
  • 系统思考:整体论
  • 5.2.4 指令执行过程
  • 基于FPGA的多级流水线加法器verilog实现,包含testbench测试文件
  • Muon小记
  • 【unitrix】 6.9 减一操作(sub_one.rs)