【重构】编写自己的简易Tomcat服务器

编写自己的简易Tomcat服务器

1. tomcat功能

  • 提供socker服务
  • 把socker获取的inputStream和outputStream封装成httpRequest对象和httpResponse对象,并进行解析inputStream
  • 对请求进行转发,找到对应的方法,然后响应到浏览器

2. 编写 myTomcat 服务器原理步骤

  • 启动 tomcat 初始化数据,并通过 key 为 url ,value w为类路径封装起来
  • 通过 socker ,把 InputStream 和 OutputStream 包装成 MyRequest 和 MyResponse 对象,解析 myRequest 流
  • 通过解析出来的 url 和 method 进行分发
  • 执行业务逻辑,通过 OutputStream 把 数据写到前台

3. 部分源码

1、MyRequest:通过输入流,对 HTTP 协议进行解析,拿到请求头的方法及 URL

package com.jiker;

import java.io.InputStream;

public class MyRequest {

    private String url;
    private String method;

    public MyRequest(InputStream inputStream){
        String httpRequest = "";
        byte[] httpRequestBytes = new byte[1024];
        int length = 0;

        try {
            if ((length = inputStream.read(httpRequestBytes)) > 0) {
                httpRequest = new String(httpRequestBytes, 0, length);
            }
            String httpHead = httpRequest.split("\n")[0];
            url = httpHead.split("\\s")[1];
            method = httpHead.split("\\s")[0];
            System.out.println(this);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}

2、MyResponse:基于 HTTP 协议的格式进行输出写入

package com.jiker;

import java.io.IOException;
import java.io.OutputStream;

public class MyResponse {

    private OutputStream outputStream;

    public MyResponse(OutputStream outputStream){
        this.outputStream = outputStream;
    }

    public void write(String context){
        StringBuffer httpResponse = new StringBuffer();
        httpResponse.append("HTTP/1.1 200 OK\n")
                .append("Content-Type: text/html\n")
                .append("\r\n")
                .append("")
                .append(context)
                .append("");
        try {
            outputStream.write(httpResponse.toString().getBytes());
            outputStream.close();
        } catch (IOException e){
            e.printStackTrace();
        }
    }
}

3、MyServlet

package com.jiker;

public abstract class MyServlet {

    public abstract void doGet(MyRequest myRequest,MyResponse myResponse);
    public abstract void doPost(MyRequest myRequest,MyResponse myResponse);

    public void service(MyRequest myRequest,MyResponse myResponse){
        if (myRequest.getMethod().equalsIgnoreCase("GET")){
            doPost(myRequest,myResponse);
        } else if (myRequest.getMethod().equalsIgnoreCase("POST")){
            doGet(myRequest,myResponse);
        }
    }

}

4、HelloServlet:继承 MyServlet ,实现 doget 和 doPost 方法

package com.jiker;

public class HelloServlet extends MyServlet {

    @Override
    public  void doGet(MyRequest myRequest,MyResponse myResponse){
        myResponse.write("get hello");
    }

    @Override
    public void doPost(MyRequest myRequest,MyResponse myResponse){
        myResponse.write("get hello");
    }
}

5、MyTomcat:核心类

package com.jiker;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class MyTomcat {

    private int port = 8080;
    private Map urlServletMap = new HashMap();

    public MyTomcat(int port){
        this.port = port;
    }

    public void start(){
        initServletMapping();
        ServerSocket servletSocket= null;
        try {
            servletSocket = new ServerSocket();
            while (true){
                Socket socket = servletSocket.accept();
                InputStream inputStream = socket.getInputStream();
                OutputStream outputStream = socket.getOutputStream();
                MyRequest myRequest = new MyRequest(inputStream);
                MyResponse myResponse = new MyResponse(outputStream);
                dispatch(myRequest,myResponse);
                socket.close();
            }
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            if (servletSocket != null){
                try {
                    servletSocket.close();
                } catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    private void initServletMapping(){
        for (ServletMapping servletMapping:ServletMappingConfig.servletMappingList){
            urlServletMap.put(servletMapping.getUrl(),servletMapping.getClazz());
        }
    }

    private void dispatch(MyRequest myRequest,MyResponse myResponse){
        String clazz = urlServletMap.get(myRequest.getUrl());
        try {
            Class myServletClass = (Class)Class.forName(clazz);
            MyServlet myServlet = myServletClass.newInstance();
            myServlet.service(myRequest,myResponse);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}

6、测试

package com.jiker.test;

import com.jiker.MyTomcat;

public class Test {
    public static  void  main(String[] args){
        new MyTomcat(8080).start();
    }
}

访问:http://localhost:8080/hello
【重构】编写自己的简易Tomcat服务器_第1张图片
myTomcat 服务器配置成功

时间:2019.6.12 20:32

你可能感兴趣的:(Tomcat)