摘要:實現一個簡單的作用我們的應用會運行在中,那么顯然請求必定是先到達的,對于請求實際上會進行如下的處理提供服務的啟動,必然是服務,支持協議。進行請求的分發一個可以為多個應用提供服務,那么就需要把下發到不同的應用。下面我們就自己來實現這三步。
實現一個簡單的Tomcat 1. Tomcat作用
我們的web應用會運行在Tomcat中,那么顯然請求必定是先到達Tomcat的,Tomcat對于請求實際上會進行如下的處理:
提供Socket服務:Tomcat的啟動,必然是Socket服務,支持http協議。
進行請求的分發:一個Tomcat可以為多個web應用提供服務,那么就需要把url下發到不同的web應用。
需要將請求和響應封裝成request和response:我們在寫后端代碼的時候都是直接使用request和response的,這是因為Tomcat已經做好了。
下面我們就自己來實現這三步。
2. 實現代碼項目結構:
src └─mytomcat BookServlet.java CarServlet.java MyRequest.java MyResponse.java MyServlet.java MyTomcat.java ServletMapping.java ServletMappingConfig.java2.1 封裝http請求和響應
package mytomcat; import java.io.IOException; import java.io.InputStream; /** * 封裝http請求 */ public class MyRequest { private String url; private String method; public MyRequest(InputStream inputStream) throws IOException { String httpRequest = ""; byte[] httpRequestBytes = new byte[1024]; int length = 0; if((length = inputStream.read(httpRequestBytes)) > 0) { httpRequest = new String(httpRequestBytes, 0, length); } String httpHead = httpRequest.split(" ")[0]; url = httpHead.split("s")[1]; method = httpHead.split("s")[0]; 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; } @Override public String toString() { return "MyRequest -- url:" + url + ",method:" + method; } }
package mytomcat; import java.io.IOException; import java.io.OutputStream; /** * 封裝http響應 */ public class MyResponse { private OutputStream outputStream; public MyResponse (OutputStream outputStream) { this.outputStream = outputStream; } public void write(String content) throws IOException { StringBuffer httpResponse = new StringBuffer(); httpResponse.append("HTTP/1.1 200 OK ") .append("Content-Type: text/html ") .append(" ") .append(content); outputStream.write(httpResponse.toString().getBytes()); outputStream.close(); } }2.2 實現不同的Servlet
package mytomcat; /** * Servlet抽象類 */ public abstract class MyServlet { public abstract void doGet(MyRequest myRequest, MyResponse myResponse); public abstract void doPost(MyRequest myRequest, MyResponse myResponse); public void service(MyRequest myRequest, MyResponse myResponse) { if(myRequest.getMethod().equalsIgnoreCase("POST")) { doPost(myRequest, myResponse); }else if(myRequest.getMethod().equalsIgnoreCase("GET")) { doGet(myRequest, myResponse); } } }
package mytomcat; import java.io.IOException; /** * 處理操作"書"的http請求 */ public class BookServlet extends MyServlet { @Override public void doGet(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[get] book..."); }catch(IOException e) { e.printStackTrace(); } } @Override public void doPost(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[post] book..."); }catch(IOException e) { e.printStackTrace(); } } }
package mytomcat; import java.io.IOException; /** * 處理操作"車"的http請求 */ public class CarServlet extends MyServlet { @Override public void doGet(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[get] car..."); }catch(IOException e) { e.printStackTrace(); } } @Override public void doPost(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[post] car..."); }catch(IOException e) { e.printStackTrace(); } } }2.3 定義Servlet映射POJO類
package mytomcat; public class ServletMapping { private String servletName; private String url; private String className; public ServletMapping(String servletName, String url, String className) { super(); this.servletName = servletName; this.url = url; this.className = className; } public String getServletName() { return servletName; } public void setServletName(String servletName) { this.servletName = servletName; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } }2.4 配置Servlet映射關系
package mytomcat; import java.util.ArrayList; import java.util.List; /** * 配置請求url和處理的servlet的對應關系 */ public class ServletMappingConfig { public static List2.5 主類servletMappingList = new ArrayList<>();; static { servletMappingList.add(new ServletMapping("Book", "/book", "mytomcat.BookServlet")); servletMappingList.add(new ServletMapping("Car", "/car", "mytomcat.CarServlet")); } }
package mytomcat; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; public class MyTomcat { private int port; //保存請求url和處理請求servlet的對應關系 private Map3. 測試urlServletMap = new HashMap (); public MyTomcat(int port) { this.port = port; } public void start() { initServletMapping(); ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); System.out.println("MyTomcat is start... 監聽端口:" + port); while(true) { System.out.println("等待請求..."); Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); MyRequest myRequest = new MyRequest(inputStream); MyResponse myResponse = new MyResponse(outputStream); //請求分發 disPatch(myRequest, myResponse); socket.close(); } }catch(IOException e) { e.printStackTrace(); }finally { if(serverSocket != null) { try { serverSocket.close(); }catch(IOException e) { e.printStackTrace(); } } } } //初始化url和處理的servlet的對應關系 private void initServletMapping() { for(ServletMapping servletMapping: ServletMappingConfig.servletMappingList) { urlServletMap.put(servletMapping.getUrl(), servletMapping.getClassName()); } } //分發處理請求 private void disPatch(MyRequest myRequest, MyResponse myResponse) { String className = urlServletMap.get(myRequest.getUrl()); //反射 try { Class myServletClass = (Class ) Class.forName(className); MyServlet myServlet = myServletClass.newInstance(); myServlet.service(myRequest, myResponse); }catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { MyTomcat myTomcat = new MyTomcat(8080); myTomcat.start(); } }
運行MyTomcat主類,然后在瀏覽器輸入http://localhost:8080/car,可以看到返回[get] car...,大功告成。
源碼地址:
https://github.com/WangJun-SCU/mytomcat
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72060.html
摘要:項目結構項目結構如下實現細節創建對象首先創建自定義的請求類,其中定義與兩個屬性,表示請求的以及請求的方式。其構造函數需要傳入一個輸入流,該輸入流通過客戶端的套接字對象得到。創建服務端套接字,并綁定某個端口。 緣起 用了那么久tomcat,突然覺得自己對它或許并沒有想象中的那么熟悉,所以趁著放假我研究了一下這只小貓咪,實現了自己的小tomcat,寫出這篇文章同大家一起分享! 照例附上gi...
摘要:前言對的管理一直有了解,但是一直沒有實際操作一遍,本文從最簡單的安裝啟動開始,通過實例的方式循序漸進的介紹了幾種管理的方式。 前言 Nginx+Tomcat對Session的管理一直有了解,但是一直沒有實際操作一遍,本文從最簡單的安裝啟動開始,通過實例的方式循序漸進的介紹了幾種管理session的方式。 nginx安裝配置 1.安裝nginx [root@localhost ~]# y...
摘要:創建一個環境最近公司正在使用開發網站應用,所以有必要了解下如何使用創建對應的環境。還好,提供了文檔的形式來組合多個容器來搭建開發環境。下一步我們將使用來構建更加復雜的開發環境。 showImg(https://segmentfault.com/img/remote/1460000011106825); 從《從最簡單的入手學習 Docker (一)》一文中,可以簡單的了解 Docker ...
摘要:在做數據分析和人工智能方面也有很多可以直接使用的算法庫。各方面都能找到優秀的組件。但開發起來復雜一些,更適合有一定規模的團隊采用。 對語言之間優勢這個問題,可以寫幾本書來具體闡述. 我嘗試簡單地說一點。不見得對,也不可能完整,僅供參考。 互聯網興起,靜態頁面不能滿足復雜的交互需求. 出現了動態技術.史前時期動態Web 開發多采用CGI 技術來實現. CGI 將腳本作為單獨的進程運行, ...
閱讀 2618·2021-11-12 10:36
閱讀 2257·2021-08-23 09:47
閱讀 1675·2019-08-30 15:44
閱讀 1400·2019-08-30 14:10
閱讀 2241·2019-08-29 16:52
閱讀 2333·2019-08-29 16:40
閱讀 1582·2019-08-29 16:17
閱讀 2407·2019-08-26 13:21