最近研究一方socket编程,由于想动手写关于socket方面的东西。然而我们知道通过URL去访问某网址,其实其底层用的就是socket,于是我就写了一个很简单的tomcat服务器,主要目地在于学习,在此分享给大家。同时提供下载源工程。
我写的工程用Maven管理的,但是我没有引入其它的JAR包,为此我就不列出pom.xml文件了。
在此简要地说明每个类的作用:
Server.java
该类的作用就是将服务提起来的,并且利用线程池。
package com.cloud.tomcat.server; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server { private static ServerSocket serverSocket; private static ExecutorService executorService; private final static int POOL_SIZE = 15; public static void main(String[] args) throws Exception { serverSocket = new ServerSocket(8080); Socket socket = null; executorService = Executors.newFixedThreadPool(POOL_SIZE); while (true) { socket = serverSocket.accept(); PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")); writer.println("HTTP/1.1 200 OK"); writer.println("Content-Type: text/html;charset=UTF-8"); writer.println(); executorService.execute(new Handler(socket, writer)); } } }
Handler.java
该类的作用是根据浏览器传过来信息做出相应的处理,同时实现Runnable接口。
package com.cloud.tomcat.server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import com.cloud.tomcat.servlet.HttpServlet; public class Handler implements Runnable { private Socket socket; private PrintWriter writer; public Handler(Socket socket, PrintWriter writer) { this.socket = socket; this.writer = writer; } @Override public void run() { try { InputStream inputStream = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String path = ""; String method = ""; while (true) { String msg = reader.readLine(); if (null == msg || "".equals(msg.trim())) { break; } String[] msgs = msg.split(" "); if (3 == msgs.length && "HTTP/1.1".equalsIgnoreCase(msgs[2])) { method = msgs[0]; path = msgs[1]; break; } } if (path.endsWith("ico")) { return; } HttpServlet httpServlet = ServletContainer.getHttpServlet(path); String html = ""; if ("GET".equals(method)) { html = httpServlet.doGet(); } else if ("POST".equals(method)) { html = httpServlet.doGet(); } writer.write(html); writer.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { writer.close(); socket.close(); } catch (Exception e) { e.printStackTrace(); } } } }
ServletContainer.java
该类首先会解析web.xml文件,然后根据url的信息,拿到相应的servlet。
package com.cloud.tomcat.server; import java.util.HashMap; import java.util.Map; import com.cloud.tomcat.model.Servlet; import com.cloud.tomcat.model.ServletMapping; import com.cloud.tomcat.servlet.HttpServlet; import com.cloud.tomcat.util.XMLUtil; public class ServletContainer { private static Map<String, Object> servletMaps = new HashMap<String, Object>(); private static Map<String, Object> servletMappingMaps = new HashMap<String, Object>(); private static Map<String, HttpServlet> servletContainer = new HashMap<String, HttpServlet>(); static { try { Map<Integer, Map<String, Object>> maps = XMLUtil.parseWebXML(); if (null != maps && 2 == maps.size()) { servletMaps = maps.get(0); servletMappingMaps = maps.get(1); } } catch (Exception e) { e.printStackTrace(); } } public static HttpServlet getHttpServlet(String path) { if (null == path || "".equals(path.trim()) || "/".equals(path)) { path = "/index"; } if (servletContainer.containsKey(path)) { return servletContainer.get(path); } if (!servletMappingMaps.containsKey(path)) { return null; } ServletMapping servletMapping = (ServletMapping) servletMappingMaps.get(path); String name = servletMapping.getName(); if (!servletMaps.containsKey(name)) { return null; } Servlet servlet = (Servlet) servletMaps.get(name); String clazz = servlet.getClazz(); if (null == clazz || "".equals(clazz.trim())) { return null; } HttpServlet httpServlet = null; try { httpServlet = (HttpServlet) Class.forName(clazz).newInstance(); servletContainer.put(path, httpServlet); } catch (Exception e) { e.printStackTrace(); } return httpServlet; } }
HttpServlet.java
为了实现起来简单方便,我自己定义了一个HttpServlet。
package com.cloud.tomcat.servlet; public interface HttpServlet { public String doGet(); public String doPost(); }
CloudServlet.java
HttpServlet的具体实现类。
package com.cloud.tomcat.servlet; public class CloudServlet implements HttpServlet { @Override public String doGet() { return this.doPost(); } @Override public String doPost() { return "<h1>Chicago at Cloud!!!</h1>"; } }
下面一一列出解析web.xml用到的类,由于我没有引入第三JAR包,可能这部分有点麻烦。
Servlet.java
package com.cloud.tomcat.model; public class Servlet { private String name; private String clazz; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } }
ServletMapping.java
package com.cloud.tomcat.model; public class ServletMapping { private String name; private String url; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
XMLUtil.java
package com.cloud.tomcat.util; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.cloud.tomcat.model.Servlet; import com.cloud.tomcat.model.ServletMapping; public class XMLUtil { public static Map<Integer, Map<String, Object>> parseWebXML() throws Exception { Map<Integer, Map<String, Object>> result = new HashMap<Integer, Map<String,Object>>(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputStream in = XMLUtil.class.getClassLoader().getResourceAsStream("web.xml"); Document document = db.parse(in); Element root = document.getDocumentElement(); NodeList xmlNodes = root.getChildNodes(); for (int i = 0; i < xmlNodes.getLength(); i++) { Node config = xmlNodes.item(i); if (null != config && config.getNodeType() == Node.ELEMENT_NODE) { String nodeName1 = config.getNodeName(); if ("servlet".equals(nodeName1)) { Map<String, Object> servletMaps = null; if (result.containsKey(0)) { servletMaps = result.get(0); } else { servletMaps = new HashMap<String, Object>(); } NodeList childNodes = config.getChildNodes(); Servlet servlet = new Servlet(); for (int j = 0; j < childNodes.getLength(); j++) { Node node = childNodes.item(j); if (null != node && node.getNodeType() == Node.ELEMENT_NODE) { String nodeName2 = node.getNodeName(); String textContent = node.getTextContent(); if ("servlet-name".equals(nodeName2)) { servlet.setName(textContent); } else if ("servlet-class".equals(nodeName2)) { servlet.setClazz(textContent); } } } servletMaps.put(servlet.getName(), servlet); result.put(0, servletMaps); } else if ("servlet-mapping".equals(nodeName1)) { Map<String, Object> servletMappingMaps = null; if (result.containsKey(1)) { servletMappingMaps = result.get(1); } else { servletMappingMaps = new HashMap<String, Object>(); } NodeList childNodes = config.getChildNodes(); ServletMapping servletMapping = new ServletMapping(); for (int j = 0; j < childNodes.getLength(); j++) { Node node = childNodes.item(j); if (null != node && node.getNodeType() == Node.ELEMENT_NODE) { String nodeName2 = node.getNodeName(); String textContent = node.getTextContent(); if ("servlet-name".equals(nodeName2)) { servletMapping.setName(textContent); } else if ("url-pattern".equals(nodeName2)) { servletMapping.setUrl(textContent); } } } servletMappingMaps.put(servletMapping.getUrl(), servletMapping); result.put(1, servletMappingMaps); } } } return result; } public static void main(String[] args) throws Exception { System.out.println(parseWebXML()); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>cloud</servlet-name> <servlet-class>com.cloud.tomcat.servlet.CloudServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cloud</servlet-name> <url-pattern>/index</url-pattern> </servlet-mapping> </web-app>
运行结果:
将Server类运行起来,然后用浏览器输入:
http://localhost:8080/index或http://localhost:8080
得到如下结果:
相关推荐
【标题】"手写Tomcat全家桶"是一个深入理解并实践Apache Tomcat服务器的项目,旨在帮助开发者通过自己动手编写代码来深入理解Tomcat的工作原理和内部机制。这个项目涵盖了从基础的HTTP服务器到复杂的Servlet容器的...
### 自己动手写Struts:构建基于MVC的Web开发框架 #### 第一篇:Web框架入门 ##### 第1章 运筹帷幄:Web框架的核心思想 - **MVC模式** - **MVC模式概述**:MVC(Model-View-Controller)是一种常用的设计模式,...
《自己动手写搜索引擎光盘源码 第一章》是一份宝贵的学习资料,旨在帮助初学者深入理解搜索引擎技术的基础。这份源码中删除了tomcat客户端程序,以优化下载速度,尤其是对网络条件较差的用户非常友好。源码分为两...
【标题】"手写仿Tomcat服务器代码"揭示了这个项目的核心目标——通过编写Java代码来模拟Tomcat服务器的关键功能。...同时,这也是一个很好的实践项目,可以帮助开发者提高自己动手实现复杂系统的能力。
**Tomcat的使用方法** Apache Tomcat是一款广泛使用的开源Java Servlet容器,它是Java EE(Enterprise Edition)的一部分,专为运行Web应用...实践出真知,动手操作是学习的最佳途径,祝你在Tomcat的世界里探索愉快!
在Android开发过程中,为了实现应用程序与服务器的数据交互,开发者经常需要搭建一个本地服务器进行测试。在本场景中,我们关注...记住,实践是最好的老师,动手尝试并根据遇到的问题调整配置,是掌握这项技能的关键。
读者可以通过阅读《How Tomcat Works》中文版来理论学习,通过分析源码来实践探索,从而掌握Tomcat的核心技术,提升自己的Java Web开发能力。无论是对初学者还是经验丰富的开发者,这都是一份极具价值的学习材料。
自己动手写Struts1 要实现一个简易的Struts1框架,你需要完成以下步骤: 1. **创建ActionServlet**:实现Servlet接口,处理HTTP请求。这里需要解析请求参数,根据ActionMapping找到对应的Action执行。 2. **编写...
Apache Tomcat是一个开源的Java Servlet容器,用于部署和运行Java Web应用程序。它是基于Sun Microsystems的Java Servlet和JavaServer ...通过阅读源代码和动手实践,你可以更好地掌握Java Web应用的部署、运行和优化。
《Tomcat 6.0最新版解压版详解与初学者指南》 Tomcat 6.0是一款广泛应用的开源Web服务器和Servlet容器,由Apache软件基金会的Tomcat项目开发。...记住,实践是最好的老师,动手操作才能真正理解Tomcat的精髓。
通过这个项目,学生不仅可以掌握JavaEE的基本概念,还能提高解决问题和动手能力,为未来开发复杂的Web应用打下坚实的基础。在实际开发中,Tomcat通常与MVC框架(如Spring MVC)结合使用,提供更强大的功能和性能优化...
中文版的书籍可以帮助中国开发者消除语言障碍,更深入地理解Tomcat的内部运作机制,而源码则提供了实际动手操作的机会,帮助开发者通过代码去探索和理解Tomcat的每个功能模块。 Tomcat工作原理的核心知识点包括: ...
apache-tomcat-7.0.88-x64,解压后安装好服务即可使用,不是安装版,自己动手配置。解压即安装,极其简单易用,很好的学习工具
【标题】"Tomcat下HttpServlet的Web应用工程"是一个基于Java J2EE技术的Web项目,它在Tomcat7服务器环境下运行。...对于初学者来说,这是一个很好的实践项目,可以帮助他们巩固理论知识,提高动手能力。
源代码压缩包"Tomcat与Java Web开发技术详解源代码.rar"包含了书中所有示例的完整实现,为读者提供了动手实践的宝贵资源。 首先,Tomcat是Apache软件基金会下的一个开源项目,是一款轻量级的应用服务器,主要支持...
提供的《How Tomcat Works 中文版.pdf》应该涵盖了这些主题,并可能包含实际案例和代码,以便读者可以动手实践。通过阅读这本书和运行书中提供的案例,你可以深入理解Tomcat的内部工作机制,提升你在Web应用开发和...
《How Tomcat Work 第二章 实例应用》深入解析 在深入探讨Tomcat工作...通过动手实践,你可以更好地理解和掌握Tomcat的工作方式,并能有效地将其应用到实际项目中。不断探索和实践,是提升Tomcat使用技巧的不二法门。
通过仿写Tomcat,你可以深入了解Web服务器的工作流程,提升对Java Web技术的理解,同时这也是一个动手实践的好机会,能够锻炼编程和问题解决能力。在实际操作中,可能会遇到各种挑战,如HTTP协议解析、多线程管理、...
9. **实战案例**:书中可能包含了一些实战项目案例,让读者能够在实际场景中应用所学知识,提升动手能力。 10. **最佳实践**:分享了作者们在长期使用和维护Tomcat过程中总结的最佳实践,帮助读者避免常见错误,...