手把手教你撸一个 Tomcat 服务器

不知道大家是否还记得前面我一篇文章中的那份简历,神一样的存在。很多人认为很难,但其实你也可以做到。走不一样的路,今天我们一起手把手的撸一个 Tomcat 吧。

你要撸一个 Tomcat,你首先得知道 Tomcat 干了哪些事。我们撸的简单点,就是把 Tomcat 解析 Http 协议,封装 Request 和 Response,调用 Servlet 这一块核心给搞出来。

明白这一点后,我们先来写一个 Socket,监听端口,解析封装请求和响应对象。

public class TomcatMain {
    // 存储 Servlet,相当于在 web.xml 中配置 Servlet
    private Map<String, String> servletMaps = new HashMap<>();
    public TomcatMain(){
        loadXml();
    }
    private void loadXml(){
        servletMaps.put("/xttblog","com.xttblog.tomcat.HelloServlet");
    }
    public void start() {
        ServerSocket server = null;
        try {
            server = new ServerSocket(8089);
            System.out.println("server on port 8080 is running...");
            while (true) {
                Socket client = server.accept();
                requestAndResponseHandle(new XttblogRequest(client.getInputStream()),
                        new XttblogResponse(client.getOutputStream()));
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void requestAndResponseHandle(XttblogRequest request,
        XttblogResponse response) {
        String className = servletMaps.get(request.getUrl());
        if (className != null) {
            try {
                Class cls = Class.forName(className);
                XttblogServlet myServlet = (XttblogServlet) cls.newInstance();
                myServlet.service(request, response);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        TomcatMain tomcat = new TomcatMain();
        tomcat.start();
    }
}

代码很简单,读取 Web.xml 这一块忽略,相当于直接读取到了 Map 中。

然后是请求 Request 部分的代码。

public class XttblogRequest {
    private String url;
    private String method;
    public XttblogRequest(InputStream is) throws IOException {
        byte[] content = new byte[1024];
        int readLen = is.read(content);
        if (readLen > 0) {
            String s = new String(content, 0, readLen);
            String[] ss = s.split("//s");
            url = ss[1];
            switch (ss[0]) {
                case "GET": {
                    method = "GET";
                    break;
                } case "POST": {
                    method = "POST";
                    break;
                }
            }
        }
    }
    public String getUrl() {
        return url;
    }
    public String getMethod() {
        return method;
    }
}

再接着封装 Response。

public class XttblogResponse {
    private OutputStream os;
    public XttblogResponse(OutputStream os) {
        this.os = os;
    }
    public void write(String content) throws IOException {
        StringBuilder sbd = new StringBuilder(128);
        String line = "/r/n";
        sbd.append("HTTP/1.0 200 ").append(line)
                .append("Content-Type:text/html").append(line)
                .append(line)
                .append("<html><body>")
                .append(content)
                .append("</body></html>");
        os.write(sbd.toString().getBytes());
    }
    public void close() throws IOException {
        os.close();
    }
}

接着是 XttblogServlet 接口。

public abstract class XttblogServlet {
    public abstract void doGet(XttblogRequest request, 
        XttblogResponse response) throws Exception;
    public abstract void doPost(XttblogRequest request, 
        XttblogResponse response) throws Exception;
    public void service(XttblogRequest request, 
        XttblogResponse response) throws Exception{
        String method = request.getMethod();
        switch (method) {
            case "GET": {
                doGet(request, response);
                break;
            }case "POST": {
                doPost(request, response);
                break;
            }
        }
    }
}

最后一步,写个 Servlet 测试我们的 Tomcat。

public class HelloServlet extends XttblogServlet{
    @Override
    public void doGet(XttblogRequest request, 
        XttblogResponse response) throws Exception {
        String say = request.getMethod() + " request,www.xttblog.com say hello";
        System.out.println(say);
        response.write(say);
    }
    @Override
    public void doPost(XttblogRequest request, 
        XttblogResponse response) throws Exception {
        String say = request.getMethod() + " request,www.xttblog.com say hello";
        System.out.println(say);
        response.write(say);
    }
}

至此,代码全部撸完。我们 main 方法启动项目。浏览器里输入 http://localhost:8089/xttblog,请求响应完美支持。

手把手教你撸一个 Tomcat 服务器
手把手教你撸一个 Tomcat 服务器

上面的代码很简单,但 Tomcat 并不简单。Tomcat 还有很多功能,里面也用到了很多设计模式,线程池,集群,虚拟目录等各种功能。想要了解更多,可以阅读 Tomcat 源码或者扫码下方海报上的二维码,我们一起在极客时间上学习 Tomcat。

手把手教你撸一个 Tomcat 服务器
极客时间《深入拆解Tomcat &Jetty》扫海报二维码购买后返现24,请加微信 xttblog

手把手教你撸一个 Tomcat 服务器

: » 手把手教你撸一个 Tomcat 服务器

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/252106.html

(0)
上一篇 2022年5月4日
下一篇 2022年5月4日

相关推荐

发表回复

登录后才能评论