首先,Tomcat是一个软件,所有的项目都能在Tomcat上加载运行,Tomcat最核心的就是Servlet集合,本身就是HashMap。Tomcat需要支持Servlet,所以有servlet底层的资源:HttpServlet抽象类、HttpRequest和HttpResponse,否则我们无法新建Servlet。
http协议:客户端和用户端进行请求和响应的过程:

这样我们就可以在webapps写项目了,一个项目有两大资源:servlet资源和静态资源,servlet本身是java类,我们让它调用doGet和doPost方法,必须继承HttpServlet,同时也需要@WebServlet注解,那么在Tomcat中就必须要有@WebServlet注解的实现,如果没有@WebServlet,我们就无法拿到相应的注解。这样我们就能成功搭建起Servlet资源。
当Http请求打过来之后,先打到socket上,处理Http请求,其本身就是连接器,从请求上能获取到请求路径和请求方法。先获取到请求路径,判断servlet容器中是否含有相同路径,如果有,再获取请求方法,判断是doGet还是doPost。

简易版tomcat的核心原理
真正的Tomcat很复杂,但它的最核心功能可以简化为:
- 监听HTTP请求(Socket 绑定 8080 端口)
- 解析HTTP请求(读取请求头、请求体)
- 找到对应的Servlet处理请求 (反射调用
service()
方法) - 返回HTTP响应(写回响应头和HTML)
手写tomcat
首先,定义Servlet接口
java
public interface servlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException;
}
其次,定义request和response
java
public class HttpServletRequest {
private String method;
private String url;
//............
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
public class HttpServletResponse {
//输出流
private OutputStream outputStream;
public HttpServletResponse(OutputStream outputStream){
this.outputStream = outputStream;
}
/**
* 返回动态资源
* @param context
*/
public void write(String context) throws IOException {
//System.out.println(context);
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());
}
}
}
然后,实现一个Httpserver
java
public class MyTomcat {
static HashMap<String, HttpServlet> routes = TomcatRoute.routes; //tomcat路由\
/**
* 分发器
*/
public void dispatch(HttpServletRequest request ,HttpServletResponse response) throws IOException {
System.out.println("URL: " + request.getUrl());
HttpServlet servlet = routes.get(request.getUrl()); //
if(servlet!=null){ //说明请求的就是我们的servlet
System.out.println("找到匹配的Servlet: " + servlet.getClass().getName());
servlet.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);
socket.close();//socket在这里关闭
}
}
//socket
public static void main(String[] args) throws IOException {
MyTomcat myTomcat = new MyTomcat();
myTomcat.start();
}
}
然后,自定义一个Servlet
java
@CYServlet(url = "/myServlet")
public class MyFirstServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
super.doPost(request, response);
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("Hello World!");
System.out.println("Servlet实例: " + this);
response.write(ResponseUtil.getResponseHeader200("hello world hhhhh"));
}
}
最后,启动服务并测试
java
public static void main(String[] args) throws IOException {
MyTomcat myTomcat = new MyTomcat();
myTomcat.start();
}
访问浏览器localhost:8080会得到:
