Java基础、中级、高级、架构面试资料

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

JAVA herman 2257浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

不知道大家是否还记得前面我一篇文章中的那份简历,神一样的存在。很多人认为很难,但其实你也可以做到。走不一样的路,今天我们一起手把手的撸一个 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 &Jetty》扫海报二维码购买后返现24,请加微信 xttblog

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 手把手教你撸一个 Tomcat 服务器