注:項目(MyEclipse)建立的時候選擇:Web Service Projecthtml
首先看看Project(FirstTomcat)的目錄結構java
|-FirstTomcattomcat
|——src服務器
| |-org.mrzhangxd.comcookie
| |-FirstRequest.javaapp
| |-FirstResponse.javasocket
| |-FirstServlet.java測試
| |-FirstTomcat.javathis
| |-FirstServletMapping.java編碼
| |_FirstServletMappingConfig.java
| |-JRE System Library[JavaSE-x.y]
| |-JAXB x.y.z Libraries
| |-JavaEE x.y Generic Library
| |-JSTL x.y.z Library
| |-JAX-RS x.y Libraries(Project Jersey x.y)
|___|_WebRoot
處理請求:
接下來一一實現
請求:FirstRequest.java
package org.mrzhangxd.com; import java.io.InputStream; /** * * @author mrzhangxd * */ public class FirstRequest { //請求路徑 private String url; //請求方法 private String method; public FirstRequest(InputStream inputStream)throws Exception{ String httpRequest = ""; byte[] httpRequestBytes = new byte[1024]; int length = 0; if((length = inputStream.read(httpRequestBytes))>0){ httpRequest = new String(httpRequestBytes,0,length); } //HTTP請求協議:首行的內容依次爲:請求方法、請求路徑以及請求協議及其對應的版本號 //GET /index /HTTP/1.1 String httpHead = httpRequest.split("\n")[0];//取出HTTP協議的首行 System.out.println(httpHead); method = httpHead.split("\\s")[0];//按照空格進行分割,第一個請求方法
url = httpHead.split("\\s")[1];//按照空格進行分割,第二個是路徑 System.out.println(this.toString()); }
public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public String toString(){ return "MyRequest[url = "+url+",method = "+method+"]";
} } |
迴應:FirstResponse.java
package org.mrzhangxd.com; import java.io.IOException; import java.io.OutputStream; /** * * @author mrzhangxd * */ public class FirstResponse { private OutputStream outputStream; public FirstResponse(OutputStream outputStream){ this.outputStream = outputStream; } //將文本轉換爲字節流 public void write(String content)throws IOException{ StringBuffer httpResponse = new StringBuffer(); httpResponse.append("HTTP/1.1 200 OK\n") .append("Content-Type;text/html\n") .append("\r\n") .append("<html><link rel = \"icon\"href = \"data:;base64,=\">") .append(content)//將頁面內容寫入 .append("</body></html>") .append(""); outputStream.write(httpResponse.toString().getBytes());//將文本轉換爲字節碼 outputStream.close(); } } |
Servlet請求處理基類:FirstServlet.java
package org.mrzhangxd.com; /** * * @author mrzhangxd * */ public abstract class FirstServlet { public void servlet(FirstRequest firstRequest,FirstResponse firstResponse){ if(firstRequest.getMethod().equalsIgnoreCase("POST")){ doPost(firstRequest,firstResponse); }else if(firstRequest.getMethod().equalsIgnoreCase("GET")){ doGet(firstRequest,firstResponse); } } private void doGet(FirstRequest firstRequest, FirstResponse firstResponse) { // TODO Auto-generated method stub } private void doPost(FirstRequest firstRequest, FirstResponse firstResponse) { // TODO Auto-generated method stub } public void service(FirstRequest firstRequest, FirstResponse firstResponse) { // TODO Auto-generated method stub } } |
下一步servlet配置:FirstServletMapping.java
package org.mrzhangxd.com;
/** * * @author mrzhangxd * */ public class FirstServletMapping { private String servletName; private String url; private String clazz;
public FirstServletMapping(String servletName, String url, String clazz) { super(); this.servletName = servletName; this.url = url; this.clazz = clazz; }
public String getServletName() { return servletName; }
public void setServeletName(String servletName) { this.servletName = servletName; }
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getClazz() { return clazz; }
public void setClazz(String clazz) { this.clazz = clazz; } } |
其餘配置:FirstServletMappingConfig.java
package org.mrzhangxd.com; import java.util.ArrayList; import java.util.List; /** * * @author mrzhangxd * */ public class FirstServletMappingConfig { public static List<FirstServletMapping> servletMappingList = new ArrayList<>(); static { servletMappingList.add(new FirstServletMapping("index", "/index", "firstTomcat.test.IndexServlet")); servletMappingList.add(new FirstServletMapping("firstblog", "/firstblog", "firstTomcat.test.MyBlog")); } } |
核心處理類:FirstTomcat.java,處理流程以下:
1) 提供Socket服務
2) 封裝請求/響應對象
3) 將不一樣的請求映射到具體的Servlet處理
這裏重點說的是,要利用 ServerSocket 經過服務器上的端口通訊 以及 accpt方法一直等待客戶端的請求
package org.mrzhangxd.com; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; /** * * @author mrzhangxd * */ public class FirstTomcat { private Integer port = 8080; //定義8080端口 private Map<String, String> urlServletMapping = new HashMap<>(); //存儲url和對應的類 public FirstTomcat(Integer port) { super(); this.port = port; } @SuppressWarnings("resource") public void start() { initServletMapping(); try { ServerSocket serverSocket = null; //實例化一個 ServerSocket 對象,表示經過服務器上的端口通訊 serverSocket = new ServerSocket(port); System.out.println("MyTomcat is starting..."); while(true) { Socket socket = serverSocket.accept(); //服務器調用 ServerSocket 類的 accept() 方法,該方法將一直等待,直到客戶端鏈接到服務器上給定的端口 InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); FirstRequest myRequest = new FirstRequest(inputStream); FirstResponse myResponse = new FirstResponse (outputStream); dispatch(myRequest, myResponse); socket.close(); } }catch(Exception e) { e.printStackTrace(); } } //初始化映射 public void initServletMapping() { for(FirstServletMapping servletMapping : FirstServletMappingConfig.servletMappingList) { urlServletMapping.put(servletMapping.getUrl(), servletMapping.getClazz()); } } //分發請求 @SuppressWarnings("unchecked") public void dispatch(FirstRequest firstRequest, FirstResponse firstResponse) { String clazz = urlServletMapping.get(firstRequest.getUrl()); try { Class<FirstServlet> firstServletClass = (Class<FirstServlet>)Class.forName(clazz); FirstServlet firstservlet = firstServletClass.newInstance(); firstservlet.service(firstRequest, firstResponse); }catch(ClassNotFoundException e) { e.printStackTrace(); }catch(InstantiationException e) { e.printStackTrace(); }catch(IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) { FirstTomcat myTomcat = new FirstTomcat(8080); myTomcat.start(); } } |
測試類按照上面類裏的註釋本身解決,測試結果略。
注:
編碼格式、註釋都參考《代碼整潔之道》