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源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章