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