Tomcat手写实现

Tomcat 服务流程

  • 1:浏览器发出请求,访问服务器,发送一个请求头信息
  • 2:根据Http协议解析对应的请求头信息
  • 3:获取请求头中的资源地址
  • 4:判断资源的类型,静态/动态
  • 5:将资源通过通道(流)返回给浏览器端

手写实现

import com.example.springbootstart.tomcat.servlet.*;

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

public class MyTomcat {
    
    
    private Integer port;

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

    public void start() throws Exception {
    
    
        initServlet();

        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("my tomcat is start, port = " + port);

        while (true) {
    
    
            //bio 此方法阻塞
            Socket socket = serverSocket.accept();

            InputStream inputStream = socket.getInputStream();
            Request request = new Request(inputStream);
            String url = request.getUrl();

            Response response = new Response(socket.getOutputStream());
//            response.write("nihao rt".getBytes());

            if ("/".equals(url)) {
    
    
                //模拟默认页面
                System.out.println("dispatch /");
            } else if (!servletMap.containsKey(url)) {
    
    
                //模拟静态资源
                System.out.println("dispatch servletMap no key " + url);
            } else {
    
    
                //模拟动态路径匹配
                dispatch(url, request, response);
            }

            socket.close();
        }
    }

    //请求分发
    private void dispatch(String url, Request request, Response response) throws InstantiationException, IllegalAccessException {
    
    
        Class<Servlet> servletClass = servletMap.get(url);
        Servlet servlet = servletClass.newInstance();
        servlet.service(request, response);
    }

    private Map<String, Class<Servlet>> servletMap = new HashMap<>();

    //初始化Servlet信息
    private void initServlet() throws ClassNotFoundException {
    
    
        List<ServletConfig> servletConfigList = ServletConfigMapping.getServletConfigList();

        for (ServletConfig servletConfig : servletConfigList) {
    
    
            servletMap.put(servletConfig.getUrlMapping(), (Class<Servlet>) Class.forName(servletConfig.getClazz()));
        }
    }

    public static void main(String[] args) throws Exception {
    
    
        MyTomcat tomcat = new MyTomcat(8080);
        tomcat.start();
    }
}

//封装请求信息
import java.io.IOException;
import java.io.InputStream;

public class Request {
    
    
    private String method;//访问方式
    private String url;//
    private InputStream inputStream;

    public Request(InputStream inputStream) throws IOException {
    
    
        this.inputStream = inputStream;
        //对于网络请求查看对应长度
        int count = 0;
        while (count == 0){
    
    
            count = inputStream.available();
        }
        //长度有效
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes);
//        System.out.println("++++++++++++++++++++++");
        String content = new String(bytes);
//        System.out.println(content);
//        System.out.println("----------------------");

        fillField(content);
    }

    public void fillField(String content){
    
    
        if ("".equals(content)){
    
    
            System.out.println("content is null");
        }else{
    
    
            //获取首行关键信息
            String firstLine = content.split("\\n")[0];
            String[] param = firstLine.split("\\s");
            method = param[0];
            url = param[1];
//            System.out.println(toString());
        }
    }

    @Override
    public String toString() {
    
    
        return "Request{" +
                "method='" + method + '\'' +
                ", url='" + url + '\'' +
                '}';
    }

    public String getMethod() {
    
    
        return method;
    }

    public String getUrl() {
    
    
        return url;
    }

    public InputStream getInputStream() {
    
    
        return inputStream;
    }
}

//封装返回结果

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

public class Response {
    
    

    private OutputStream outputStream;

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

    public void write(byte[] content) {
    
    
        try {
    
    
            outputStream.write(content);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

}

package com.example.springbootstart.tomcat.servlet;

public class RtServlet extends Servlet{
    
    
    @Override
    public void doGet(Request request, Response response) {
    
    
        System.out.println("RtServlet doGet is start");
        response.write("RtServlet doGet".getBytes());
    }

    @Override
    public void doPost(Request request, Response response) {
    
    
        System.out.println("RtServlet doPost is start");
        response.write("RtServlet doPost".getBytes());
    }
}

package com.example.springbootstart.tomcat.servlet;

public abstract  class Servlet {
    
    

    public abstract void doGet(Request request, Response response);

    public abstract void doPost(Request request, Response response);

    public void service(Request request, Response response){
    
    
        if("GET".equals(request.getMethod())){
    
    
            doGet(request, response);
        }else{
    
    
            doPost(request, response);
        }
    }
}

package com.example.springbootstart.tomcat.servlet;

public class ServletConfig {
    
    
    private String urlMapping;//请求路径
    private String name;
    private String clazz;

    public ServletConfig(String urlMapping, String name, String clazz) {
    
    
        this.urlMapping = urlMapping;
        this.name = name;
        this.clazz = clazz;
    }

    public String getUrlMapping() {
    
    
        return urlMapping;
    }

    public String getClazz() {
    
    
        return clazz;
    }
}

//url java 映射配置类
import java.util.ArrayList;
import java.util.List;

public class ServletConfigMapping {
    
    

    private static List<ServletConfig> servletConfigList = null;

    static {
    
    
        servletConfigList = new ArrayList<>();
        servletConfigList.add(new ServletConfig("/doget", "rtServlet",
                "com.example.springbootstart.tomcat.servlet.RtServlet"));
    }


    public static List<ServletConfig> getServletConfigList() {
    
    
        return servletConfigList;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44971379/article/details/120962935