Tomcat服务器的模拟实现学习解析Http协议、反射、xml解析等

模拟tomcat机制手写一个简单的Tomcat服务器,主要功能有可以获得请求参数,还可以对浏览器做出响应,底层采用http协议,通过用户请求信息,解析请求信息,并且封装了响应信息,可以向浏览器响应网页,也可以响应文字,原理就是通过IO流读取本地网页信息,将其转化为字符串输出到浏览器。并且可以针对每一个请求,服务器都会分发一个单独的线程区处理他。
核心代码如下:
源码在最底部。
源码结构:
这里写图片描述
服务器端:

public class Server {

    ServerSocket server;
    public static final String CRLF="\r\n";
    public static final String BLANK=" ";

    private boolean isShutDown= false;
    public static void main(String[] args) {
        Server s = new Server();
        s.start();
    }
    /**
     * 启动方法
     * */
    public void start() {
        start(8888);
    }
    /**
     *指定端口的启动方法 
     * @param i
     */
    public void start(int port) {
        try {
            server = new ServerSocket(port);
            this.recive();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 接受客户端的请求
     */
    private void recive() {
        try {
            while(!isShutDown) {
                new Thread(new Dispatcher(server.accept())).start();
            }
        } catch (IOException e) {
            Stop();
    }
}
    /**
     * 停止服务器
     */
    private void Stop() {
        isShutDown = true;      
        CloseUtil.closeSocket(server);
    }
}

下面是分发器:

/**
 * 一个请求与响应就一个此对象
 *@author 莱格
 */
public class Dispatcher implements Runnable {
    private Socket client;
    private Request req;
    private Response rep;
    private int code =200;//状态码默认为200
    /**
     * 构造一个分发器
     * @param accept
     */
    public Dispatcher(Socket client) {
        this.client = client;
        try {
            req = new Request(client.getInputStream());
            rep = new Response(client.getOutputStream());
        } catch (IOException e) {
            code = 500;
            return;
        }
    }

    @Override
    public void run() {
        try {
//          Servlet serv = WebApp.getServlet(req.getUrl());
            Servlet serv = ServletFactory.getServlet(req.getUrl());
            System.out.println(req.getUrl());
//          if (req.getUrl() == ParseWebXml.readDocument().) {
//              
//          }
            if (null == serv) {
                this.code = 404;
            }else {
                serv.service(req, rep);
            }
            rep.pushTOClient(code);
        } catch (Exception e) {
            e.printStackTrace();
            this.code = 500;
            try {
                rep.pushTOClient(500);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            req.close();
            rep.close();
            CloseUtil.closeSocket(client);
        }
    }

}

解析http协议的请求信息,给出源码结构,
这里写图片描述
封装了响应信息:
这里写图片描述

抽象一个servlet父类,通过继承此servlet,重写相应的方法,就可以完成相应的业务。

/**
 * 
 * 抽象为一个父类
 *@author 莱格
 */
public abstract class Servlet {
    public void service(Request req,Response rep) throws Exception{
        this.doGet(req, rep);
        this.doPost(req, rep);
    }
    protected abstract void doGet(Request req,Response rep) throws Exception;
    protected abstract void doPost(Request req,Response rep) throws Exception;


}

以下是解析web.xml源码结构。

这里写图片描述

整体的大概源码结构解释这样!

接下来,把此服务器打成j可执行的jar包,跑一个登录注册案例。
下面是登录注册案例的整体项目结构:
这里写图片描述
其中里面的springIoc.jar是楼主模拟springIoc的思想,自定义的一个简易springIoc容器.

接下来是案例演示:
这里写图片描述
这里写图片描述

用wanger登录
这里写图片描述
这里写图片描述

至此,整个小demo就跑完了。
下面贴出源码:
http服务器源码下载
案例代码:httpserver里面好像也附带了一个小demo,也可以自己写很简单的。
上述代码里面的springioc源码


版权声明:本文为z_565282532原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。