自动动手写Tomcat
来源:互联网 发布:mac os版本是什么意思 编辑:程序博客网 时间:2024/05/02 02:00
最近研究一方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
得到如下结果:
阅读全文
0 0
- 自动动手写Tomcat
- 自动动手写发包工具
- 简单圆球水波动。手写
- 手写实现Tomcat服务器
- 手写tomcat 加手写线程池结合
- Nginx自动动
- 适配 - 手写 IOS自动布局
- 利用netty自己手写一个tomcat
- 手写Tomcat容器加载静态资源
- Eclipse自动生成FindViewById,不用手写
- 手写
- Tomcat下手动配置一个项目
- ngnix反向代理tomcat,动静态分离
- 谁动了我的自动播放?
- 动网论坛自动回帖程序
- CodeMatic动软自动生成Nhibernate
- 基于jquery的自动补全自己手写的
- 基于jquery的自动补全自己手写的
- mongodb dirver for java【读取操作】
- 设计模式之二装饰者模式
- 手写简易WEB服务器
- 我的App全栈之路(1)环境的搭建
- iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇
- 自动动手写Tomcat
- Android图片setBackgroundResource和setImageResource的区别
- ABAQUS的二次开发-UMAT
- Python常用库安装小记
- mysql中的select limit statement
- 设计模式之三静态代理模式
- redis 启动登陆问题
- iOS黑魔法-Method Swizzling(全局hook,行为统计)
- PHP 函数 数组