手写tomcat——编写一个提供servlet能力的 http服务器
2024-09-05 17:15:31
点击查看代码
package com.grady.diytomcat;
import com.grady.diytomcat.handler.RequestHandler;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
public class DiyTomcat {
private int port = 8080;
public static final HashMap<String, DiyServlet> SERVLET_MAPPING = new HashMap<>();
public static final HashMap<String,String> URL_MAPPING = new HashMap<>();
static {
loadServlet();
}
private static void loadServlet() {
try {
//获取web.xml目录地址
String path = DiyTomcat.class.getResource("/").getPath();
SAXReader reader = new SAXReader();
//读取web.xml文件
Document document = reader.read(new File(path + "web.xml"));
//获取根标签(servlet和servlet-mapping),放在一个List中
Element rootElement = document.getRootElement();
List<Element> elements = rootElement.elements();
//循环将映射写进map映射里
for(Element element : elements){
if ("servlet".equalsIgnoreCase(element.getName())){
Element servletName = element.element("servlet-name");
Element servletClass = element.element("servlet-class");
//需要注意的是servletMapping映射的第二个参数,要通过反射的方式进行实例化
SERVLET_MAPPING.put(servletName.getText(),
(DiyServlet) Class.forName(servletClass.getText().trim()).newInstance());
}else if ("servlet-mapping".equalsIgnoreCase(element.getName())){
Element servletName = element.element("servlet-name");
Element urlPattern = element.element("url-pattern");
URL_MAPPING.put(urlPattern.getText(), servletName.getText());
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept();
RequestHandler requestHandler=new RequestHandler(socket);
// 一个 socket 一个线程
new Thread(requestHandler).start();
}
}
}
1. 根据tomcat的特性,首先是要有解析web.xml的能力
loadServlet
方法即是通过dom4j的能力来解析web.xml,经其中的内容创建成对应的数据结构缓存到SERVLET_MAPPING
和URL_MAPPING
中
待解析的web.xml的内容,由于是单元测试测试,所以在test
的resource
目录下
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>com.grady.diytomcat.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
2. 由于第一个版本 是单线程的,所有第一个版本只能串行执行请求,这个版本改为每接收到一个请求就创建一条线程来处理请求中的内容
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept();
RequestHandler requestHandler=new RequestHandler(socket);
// 一个 socket 一个线程
new Thread(requestHandler).start();
}
}
完整代码:
https://github.com/ZhongJinHacker/diy-tomcat/tree/bio-tomcat
最新文章
- PHP Lex Engine Sourcecode Analysis(undone)
- BST树
- 【转载】分析商品日均销量(DMS)对促销商品选择的意义
- jQuery事件与动画
- OCA读书笔记(13) - 性能管理
- jquery 调用wcf 的SOA架构,将三层架构运用到SOA的架构中来(第四天)
- 微信扫码下载APP
- 如何更简单方便地执行SQL操作?
- Dingo 的安装
- 100-days: fourteen
- Linux学习之文件系统常用命令(七)
- CentOS下下载软件,不安装的方法
- [CQOI2007]涂色
- SQL 增删改查
- UVA 350 Pseudo-Random Numbers
- python16_day37【爬虫2】
- 在jenkins和sonar中集成jacoco(一)--使用jacoco收集单元测试的覆盖率
- HDU 6188 Duizi and Shunzi 贪心
- No resources found. Error from server (NotAcceptable): unknown (get pods)
- DotNetCasClient加载失败问题分析
热门文章
- SAP Web Dynpro - 个性化和配置
- 在VMware Workstation 16上安装Windows7虚拟机以及VMware tools安装失败解决方法
- mysql-安装(windows版本)与登录
- Nginx+Keepalived+VIP漂移实现HA高可用技术之详细教程
- (数据科学学习手札140)详解geopandas中基于pyogrio的矢量读写引擎
- .NetCore|.Net6 gRPC服务开发及本地调试
- LAMP架构部署及配置
- 工作流引擎在vivo营销自动化中的应用实践 | 引擎篇03
- ExceptionLess的安装、配置、使用
- 【每天学一点-04】使用脚手架搭建 React+TypeScript+umi.js+Antd 项目