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

相关文章:

  • LINUX720 SWAP扩容;新增逻辑卷;逻辑卷扩容;数据库迁移;gdisk
  • DAY 20 奇异值分解(SVD)
  • RocketMQ核心编程模型
  • 咨询进阶——解读业务流程优化与重组【附全文阅读】
  • 5.2.4 指令执行过程
  • 【原创】微信小程序添加TDesign组件
  • ChatIM项目语音识别安装与使用
  • ARFoundation系列讲解 - 101 VisionPro 真机调试
  • USRP B210生成信号最大带宽测试之BPSK
  • 人脸识别:AI 如何精准 “认人”?
  • FreeSwitch编译部署
  • 【星海出品】python安装调试篇
  • 【数据集】NOAA 全球监测实验室(GML)海洋边界层(MBL)参考简介
  • Docker实践:使用Docker部署WhoDB开源轻量级数据库管理工具
  • 传输层协议 TCP
  • Java什么是原子性
  • Java SpringBoot 对接FreeSwitch
  • AtCoder Beginner Contest 415
  • Web-SQL注入数据库类型用户权限架构分层符号干扰利用过程发现思路
  • 向日葵远程命令执行漏洞
  • 《深入C++多态机制:从虚函数表到运行时类型识别》​
  • IDEA中使用Tomcat两种方式
  • C51单片机学习笔记——定时器与中断
  • API接口签名和敏感信息加密使用国密SM方案
  • 上电复位断言的自动化
  • go-redis Pipeline 与事务
  • 《计算机网络》实验报告五 DNS协议分析与测量
  • Dockerfile配置基于 Python 的 Web 应用镜像
  • 随着GPT-5测试中泄露OpenAI 预计将很快发布 揭秘GPT-5冲击波:OpenAI如何颠覆AI战场,碾压谷歌和Claude?
  • 单片机启动流程和启动文件详解