日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自己动手写Tomcat

發(fā)布時間:2025/6/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自己动手写Tomcat 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天看到有人寫了個簡單的tomcat,讓我想起多年以前自己也寫了個demo,興奮了好意振。貼出來分享下。有些簡陋... ??自定義服務(wù)器及瀏覽器.rar


轉(zhuǎn):

最近研究一方socket編程,由于想動手寫關(guān)于socket方面的東西。然而我們知道通過URL去訪問某網(wǎng)址,其實(shí)其底層用的就是socket,于是我就寫了一個很簡單的tomcat服務(wù)器,主要目地在于學(xué)習(xí),在此分享給大家。同時提供下載源工程。

?

我寫的工程用Maven管理的,但是我沒有引入其它的JAR包,為此我就不列出pom.xml文件了。

在此簡要地說明每個類的作用:

?

Server.java

該類的作用就是將服務(wù)提起來的,并且利用線程池。

view sourceprint? 01.package?com.cloud.tomcat.server; 02.? 03.import?java.io.OutputStreamWriter; 04.import?java.io.PrintWriter; 05.import?java.net.ServerSocket; 06.import?java.net.Socket; 07.import?java.util.concurrent.ExecutorService; 08.import?java.util.concurrent.Executors; 09.? 10.public?class?Server { 11.private?static?ServerSocket serverSocket; 12.private?static?ExecutorService executorService; 13.private?final?static?int?POOL_SIZE =?15; 14.? 15.public?static?void?main(String[] args)?throws?Exception { 16.serverSocket =?new?ServerSocket(8080); 17.Socket socket =?null; 18.executorService = Executors.newFixedThreadPool(POOL_SIZE); 19.? 20.while?(true) { 21.socket = serverSocket.accept(); 22.PrintWriter writer =?new?PrintWriter(newOutputStreamWriter(socket.getOutputStream(),?"UTF-8")); 23.writer.println("HTTP/1.1 200 OK"); 24.writer.println("Content-Type: text/html;charset=UTF-8"); 25.writer.println(); 26.? 27.executorService.execute(new?Handler(socket, writer)); 28.} 29.} 30.}


Handler.java

該類的作用是根據(jù)瀏覽器傳過來信息做出相應(yīng)的處理,同時實(shí)現(xiàn)Runnable接口。

view sourceprint? 01.package?com.cloud.tomcat.server; 02.? 03.import?java.io.BufferedReader; 04.import?java.io.IOException; 05.import?java.io.InputStream; 06.import?java.io.InputStreamReader; 07.import?java.io.PrintWriter; 08.import?java.net.Socket; 09.? 10.import?com.cloud.tomcat.servlet.HttpServlet; 11.? 12.public?class?Handler?implements?Runnable { 13.private?Socket socket; 14.private?PrintWriter writer; 15.? 16.public?Handler(Socket socket, PrintWriter writer) { 17.this.socket = socket; 18.this.writer = writer; 19.} 20.? 21.@Override 22.public?void?run() { 23.try?{ 24.InputStream inputStream = socket.getInputStream(); 25.BufferedReader reader =?new?BufferedReader(newInputStreamReader(inputStream)); 26.String path =?""; 27.String method =?""; 28.? 29.while?(true) { 30.String msg = reader.readLine(); 31.if?(null?== msg ||?"".equals(msg.trim())) { 32.break; 33.} 34.? 35.String[] msgs = msg.split(" "); 36.if?(3?== msgs.length &&?"HTTP/1.1".equalsIgnoreCase(msgs[2])) { 37.method = msgs[0]; 38.path = msgs[1]; 39.break; 40.} 41.} 42.? 43.if?(path.endsWith("ico")) { 44.return; 45.} 46.? 47.HttpServlet httpServlet = ServletContainer.getHttpServlet(path); 48.String html =?""; 49.if?("GET".equals(method)) { 50.html = httpServlet.doGet(); 51.}?else?if?("POST".equals(method)) { 52.html = httpServlet.doGet(); 53.} 54.writer.write(html); 55.writer.flush(); 56.}?catch?(IOException e) { 57.e.printStackTrace(); 58.}?finally?{ 59.try?{ 60.writer.close(); 61.socket.close(); 62.}?catch?(Exception e) { 63.e.printStackTrace(); 64.} 65.} 66.? 67.} 68.? 69.}
ServletContainer.java


該類首先會解析web.xml文件,然后根據(jù)url的信息,拿到相應(yīng)的servlet。


view sourceprint? 01.package?com.cloud.tomcat.server; 02.? 03.import?java.util.HashMap; 04.import?java.util.Map; 05.? 06.import?com.cloud.tomcat.model.Servlet; 07.import?com.cloud.tomcat.model.ServletMapping; 08.import?com.cloud.tomcat.servlet.HttpServlet; 09.import?com.cloud.tomcat.util.XMLUtil; 10.? 11.public?class?ServletContainer { 12.private?static?Map<String, Object> servletMaps =?new?HashMap<String, Object>(); 13.private?static?Map<String, Object> servletMappingMaps =?new?HashMap<String, Object>(); 14.private?static?Map<String, HttpServlet> servletContainer =?new?HashMap<String, HttpServlet>(); 15.? 16.static?{ 17.try?{ 18.Map<Integer, Map<String, Object>> maps = XMLUtil.parseWebXML(); 19.if?(null?!= maps &&?2?== maps.size()) { 20.servletMaps = maps.get(0); 21.servletMappingMaps = maps.get(1); 22.} 23.}?catch?(Exception e) { 24.e.printStackTrace(); 25.} 26.} 27.? 28.public?static?HttpServlet getHttpServlet(String path) { 29.? 30.if?(null?== path ||?"".equals(path.trim()) ||?"/".equals(path)) { 31.path =?"/index"; 32.} 33.? 34.if?(servletContainer.containsKey(path)) { 35.return?servletContainer.get(path); 36.} 37.? 38.if?(!servletMappingMaps.containsKey(path)) { 39.return?null; 40.} 41.ServletMapping servletMapping = (ServletMapping) servletMappingMaps.get(path); 42.String name = servletMapping.getName(); 43.? 44.if?(!servletMaps.containsKey(name)) { 45.return?null; 46.} 47.Servlet servlet = (Servlet) servletMaps.get(name); 48.String clazz = servlet.getClazz(); 49.? 50.if?(null?== clazz ||?"".equals(clazz.trim())) { 51.return?null; 52.} 53.? 54.HttpServlet httpServlet =?null; 55.try?{ 56.httpServlet = (HttpServlet) Class.forName(clazz).newInstance(); 57.servletContainer.put(path, httpServlet); 58.}?catch?(Exception e) { 59.e.printStackTrace(); 60.} 61.return?httpServlet; 62.} 63.}


HttpServlet.java

為了實(shí)現(xiàn)起來簡單方便,我自己定義了一個HttpServlet。


view sourceprint? 1.package?com.cloud.tomcat.servlet; 2.? 3.public?interface?HttpServlet { 4.public?String doGet(); 5.public?String doPost(); 6.}


CloudServlet.java

HttpServlet的具體實(shí)現(xiàn)類。


view sourceprint? 01.package?com.cloud.tomcat.servlet; 02.? 03.public?class?CloudServlet?implements?HttpServlet { 04.? 05.@Override 06.public?String doGet() { 07.return?this.doPost(); 08.} 09.? 10.@Override 11.public?String doPost() { 12.return?"<h1>Chicago at Cloud!!!</h1>"; 13.} 14.? 15.}


下面一一列出解析web.xml用到的類,由于我沒有引入第三JAR包,可能這部分有點(diǎn)麻煩。

Servlet.java


view sourceprint? 01.package?com.cloud.tomcat.model; 02.? 03.public?class?Servlet { 04.private?String name; 05.private?String clazz; 06.? 07.public?String getName() { 08.return?name; 09.} 10.? 11.public?void?setName(String name) { 12.this.name = name; 13.} 14.? 15.public?String getClazz() { 16.return?clazz; 17.} 18.? 19.public?void?setClazz(String clazz) { 20.this.clazz = clazz; 21.} 22.}

ServletMapping.java


view sourceprint? 01.package?com.cloud.tomcat.model; 02.? 03.public?class?ServletMapping { 04.private?String name; 05.private?String url; 06.? 07.public?String getName() { 08.return?name; 09.} 10.? 11.public?void?setName(String name) { 12.this.name = name; 13.} 14.? 15.public?String getUrl() { 16.return?url; 17.} 18.? 19.public?void?setUrl(String url) { 20.this.url = url; 21.} 22.} XMLUtil.java



view sourceprint? 01.package?com.cloud.tomcat.util; 02.? 03.import?java.io.InputStream; 04.import?java.util.HashMap; 05.import?java.util.Map; 06.? 07.import?javax.xml.parsers.DocumentBuilder; 08.import?javax.xml.parsers.DocumentBuilderFactory; 09.? 10.import?org.w3c.dom.Document; 11.import?org.w3c.dom.Element; 12.import?org.w3c.dom.Node; 13.import?org.w3c.dom.NodeList; 14.? 15.import?com.cloud.tomcat.model.Servlet; 16.import?com.cloud.tomcat.model.ServletMapping; 17.? 18.public?class?XMLUtil { 19.? 20.public?static?Map<Integer, Map<String, Object>> parseWebXML()?throws?Exception { 21.Map<Integer, Map<String, Object>> result =?new?HashMap<Integer, Map<String,Object>>(); 22.DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 23.DocumentBuilder db = dbf.newDocumentBuilder(); 24.? 25.InputStream in = XMLUtil.class.getClassLoader().getResourceAsStream("web.xml"); 26.Document document = db.parse(in); 27.Element root = document.getDocumentElement(); 28.NodeList xmlNodes = root.getChildNodes(); 29.for?(int?i =?0; i < xmlNodes.getLength(); i++) { 30.Node config = xmlNodes.item(i); 31.if?(null?!= config && config.getNodeType() == Node.ELEMENT_NODE) { 32.String nodeName1 = config.getNodeName(); 33.if?("servlet".equals(nodeName1)) { 34.Map<String, Object> servletMaps =?null; 35.if?(result.containsKey(0)) { 36.servletMaps = result.get(0); 37.}?else?{ 38.servletMaps =?new?HashMap<String, Object>(); 39.} 40.? 41.NodeList childNodes = config.getChildNodes(); 42.Servlet servlet =?new?Servlet(); 43.for?(int?j =?0; j < childNodes.getLength(); j++) { 44.Node node = childNodes.item(j); 45.if?(null?!= node && node.getNodeType() == Node.ELEMENT_NODE) { 46.String nodeName2 = node.getNodeName(); 47.String textContent = node.getTextContent(); 48.if?("servlet-name".equals(nodeName2)) { 49.servlet.setName(textContent); 50.}?else?if?("servlet-class".equals(nodeName2)) { 51.servlet.setClazz(textContent); 52.} 53.} 54.} 55.servletMaps.put(servlet.getName(), servlet); 56.? 57.result.put(0, servletMaps); 58.}?else?if?("servlet-mapping".equals(nodeName1)) { 59.Map<String, Object> servletMappingMaps =?null; 60.if?(result.containsKey(1)) { 61.servletMappingMaps = result.get(1); 62.}?else?{ 63.servletMappingMaps =?new?HashMap<String, Object>(); 64.} 65.? 66.NodeList childNodes = config.getChildNodes(); 67.ServletMapping servletMapping =?new?ServletMapping(); 68.for?(int?j =?0; j < childNodes.getLength(); j++) { 69.Node node = childNodes.item(j); 70.if?(null?!= node && node.getNodeType() == Node.ELEMENT_NODE) { 71.String nodeName2 = node.getNodeName(); 72.String textContent = node.getTextContent(); 73.if?("servlet-name".equals(nodeName2)) { 74.servletMapping.setName(textContent); 75.}?else?if?("url-pattern".equals(nodeName2)) { 76.servletMapping.setUrl(textContent); 77.} 78.} 79.} 80.servletMappingMaps.put(servletMapping.getUrl(), servletMapping); 81.? 82.result.put(1, servletMappingMaps); 83.} 84.} 85.} 86.return?result; 87.} 88.? 89.public?static?void?main(String[] args)?throws?Exception { 90.System.out.println(parseWebXML()); 91.} 92.} web.xml



view sourceprint? 01.<?xml?version="1.0"?encoding="UTF-8"?> 02.<web-app?xmlns="http://java.sun.com/xml/ns/javaee" 03.xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 04.xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 05.version="2.5"> 06.? 07.<servlet> 08.<servlet-name>cloud</servlet-name> 09.<servlet-class>com.cloud.tomcat.servlet.CloudServlet</servlet-class> 10.</servlet> 11.? 12.<servlet-mapping> 13.<servlet-name>cloud</servlet-name> 14.<url-pattern>/index</url-pattern> 15.</servlet-mapping> 16.</web-app>


運(yùn)行結(jié)果:

將Server類運(yùn)行起來,然后用瀏覽器輸入:

http://localhost:8080/index或http://localhost:8080

得到如下結(jié)果:


?



?


總結(jié)

以上是生活随笔為你收集整理的自己动手写Tomcat的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。