2008年10月16日 星期四

實現簡單的Web容器

一個類似Tomcat的容器,不過只是模擬Web容器的解析過程,只做了簡單的解析HTML。
首先用Java IDE建立一個普通的Java Project,要解析web少不了Request和Response對象,所以在工程(項目)裡建立兩個類:MyHttpServletRequest(對應HttpServletRequest)、MyHttpServletResponse(對應HttpServletResponse),如下:

//
MyHttpServletRequest.java
package com.kalman03.servlet;

import java.io.BufferedReader;
import java.io.IOException;

public class MyHttpServletRequest{
private BufferedReader br;
private String header;
public MyHttpServletRequest(BufferedReader br){
try{
this.br = br;
this.header = br.readLine();// GET /index.html HTTP/1.1
}catch(IOException ex){
ex.printStackTrace();
}
}

public String getURL(){
String [] temp
= header.split(" ");
return temp[1].substring(1);
}
}





//MyHttpServletResponse.java
package com.kalman03.servlet;

import java.io.PrintWriter;

public class MyHttpServletResponse{
private PrintWriter out;
public MyHttpServletResponse(PrintWriter out){
this.out = out;
out.println(
"HTTP/1.1 200 OK");
}

public PrintWriter getWriter(){
return out;
}
}


構造一個抽像類MyHttpServlet:
//MyHttpServlet.java
package com.kalman03.servlet;

public abstract class MyHttpServlet{
public abstract void doGet(MyHttpServletRequest request,MyHttpServletResponse response)throws Exception;
public abstract void doPost(MyHttpServletRequest request,MyHttpServletResponse response)throws Exception;
}


用MyServlet類實現上面MyHttpServlet抽像類:
//MyServlet.java
package com.kalman03.servlet.ext;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.File;
import java.io.FileReader;
import com.kalman03.servlet.MyHttpServlet;
import com.kalman03.servlet.MyHttpServletRequest;
import com.kalman03.servlet.MyHttpServletResponse;

//该类继承MyHttpServlet类,实现其中的doGet(),doPost()方法
public class MyServlet extends MyHttpServlet {
private PrintWriter out;
private String url;

public void doGet(MyHttpServletRequest request,
MyHttpServletResponse response)
throws Exception {
this.out = response.getWriter();
url
= request.getURL();
if (url.equals("")) {
url
= "index.html";
}
File file
= new File(url);
FileReader fr
= new FileReader(file);
BufferedReader brR
= new BufferedReader(fr);
String temp;
while ((temp = brR.readLine()) != null) {
out.println(temp);
}
out.close();
brR.close();
fr.close();
}

public void doPost(MyHttpServletRequest request,
MyHttpServletResponse response)
throws Exception {
this.doGet(request, response);
}
}



跑一個線程監聽類MyWebService:
//MyWebService.java
package com.kalman03.servlet;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class MyWebService {
public MyWebService(MyHttpServlet ms) {
try {
ServerSocket ss
= new ServerSocket(2008);
while (true) {
Socket s
= ss.accept();
new myRunnable(s, ms).start();
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}



//線程監聽
class myRunnable extends Thread {
private Socket s;
private MyHttpServlet ms;
public myRunnable(Socket s, MyHttpServlet ms) {
this.s = s;
this.ms = ms;
}

public void run() {
try {
BufferedReader br
= new BufferedReader(new InputStreamReader(s.
getInputStream()));
PrintWriter out
= new PrintWriter(s.getOutputStream(), true);
MyHttpServletRequest req
= new MyHttpServletRequest(br);
MyHttpServletResponse rep
= new MyHttpServletResponse(out);
ms.doGet(req, rep);
br.close();
out.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}


至此大工基本告成,再來一個main方法(MainClass類)就OK了:
//MainClass.java
package com.kalman03.test;

import com.kalman03.servlet.MyWebService;
import com.kalman03.servlet.ext.MyServlet;

public class MainClass {
public static void main (String[] args) {
new MyWebService(new MyServlet());
}
}

運行,OK!一個web容器已經啟動,當你在剛建的工程(項目)目錄下丟一個HTML(比如welcome.html),在瀏覽器裡輸入http://127.0.0.1:2008/welcome.html,即可解析welcome.html。

補充一下,這裡設置的默認端口為2008,當沒有指定具體頁面時候,尋找的是index.html

沒有留言: