专栏首页带你回家手写tomcat+servlet

手写tomcat+servlet

写程序一定要有思路,思路很重要!

一、我们分两步第一步先实现手写tomcat,第二部写servlet

所用技术:

1、soket通信 IO流

2、http请求与相应

3、解析xml

4、java反射技术

导入所需要的jar:

<dependencies>
  	 	<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
		<dependency>
		    <groupId>dom4j</groupId>
		    <artifactId>dom4j</artifactId>
		    <version>1.6.1</version>
		</dependency>
  </dependencies>

项目目录结构:

现在开始我们的第一步,手写tomcat

新建 Request 类:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Request {
	 
	 private String method;
	 private String url;

	 public Request(InputStream inputStream) throws IOException {
	        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
	        String[] methodAndUrl = bufferedReader.readLine().split(" ");
	        this.method= methodAndUrl[0];
	        this.url=methodAndUrl[1];
	        
	        System.out.println(method);
	        System.out.println(url);
	        
	    }

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}
	 
	 
}

Response 类:

import java.io.IOException;
import java.io.OutputStream;

public class Response {
	
	public OutputStream outputStream;
	
	public String wirte;
	

    public static final String responseHeader="HTTP/1.1 200 \r\n"
            + "Content-Type: text/html\r\n"
            + "\r\n";

    public Response(OutputStream outputStream) throws IOException {
        this.outputStream= outputStream;
    }

	public String getWirte() {
		return wirte;
	}

	public void setWirte(String wirte) {
		this.wirte = wirte;
	}
    
   
    
    
}

SocketProcess 类:

import java.io.OutputStream;
import java.net.Socket;
import java.util.Map;

public class SocketProcess extends Thread{
	
	  protected Socket socket;

	    public SocketProcess(Socket socket){
	        this.socket = socket;
	    } 

	    @Override
	    public void run() {
	        try {
	            Request request = new Request(socket.getInputStream());
	            Response response = new Response(socket.getOutputStream());
	            
	            
//	            Map<String, Object> map = Mytomcat.servletMapping;
//	            
//	            System.out.println("map大小为:"+map.size());
//	            for (Map.Entry<String, Object> entry : map.entrySet()) { 
//	              System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); 
//	            }
	         
	            //从映射中找
	            System.out.println(request.getUrl());
	            String servelName = (String) Mytomcat.servletMapping.get(request.getUrl());
	            System.out.println(servelName);
	            
	            if(servelName!=null && !servelName.isEmpty()) {
	            	 
	            	 //映射有的话找到对应的对象
	            	  Servelt servlet = (Servelt) Mytomcat.servlet.get(servelName);
	                  if(servlet!=null) {
	                  	servlet.doGet(request, response);
	                  	
	                  }else {
	                  	System.out.println("找不到对应的servlet");
	                  }
	            	
	            }else {
	            	System.out.println("找不到对应的servletMapping");
	            }
	            
	            String res = Response.responseHeader+response.getWirte();
                OutputStream outputStream = socket.getOutputStream();
                
                outputStream.write(res.getBytes("GBK"));
                outputStream.flush();
                outputStream.close();

	        }catch (Exception ex){
	            ex.printStackTrace();
	        }finally {
	            if (socket != null) {
	                try {
	                    socket.close();
	                } catch (Exception e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }
}

Mytomcat

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;

import org.dom4j.Element;

public class Mytomcat {
	 private static final int port = 8099;
	
	 public static final HashMap<String, Object> servletMapping = new HashMap<String, Object>();
	 
	 public static final HashMap<String, Object> servlet = new HashMap<String, Object>();
	 
	 private void init() {

	        InputStream io = null;

	        String basePath;

	        try {
	        	System.out.println("加载配置文件开始");
	            //读取web.xml 
	        	UtilsXml xml = new UtilsXml(UtilsXml.class.getResource("/")+"web.xml");
	        	//讲所有的类都存储到容器中 并且创造对象
	        	List<Element> list = xml.getNodes("servlet");
	        	for (Element element : list) {
	        		servlet.put(element.element("servlet-name").getText(), Class.forName(element.element("servlet-class").getText()).newInstance());	        		
				}
	        	//映射关系创建
	        	List<Element> list2 = xml.getNodes("servlet-mapping");
	        	for (Element element : list2) {
	        		servletMapping.put(element.element("url-pattern").getText(), element.element("servlet-name").getText());	        		
				}
	        	System.out.println("加载配置文件结束");
	        	
	        } catch (Exception ex) {
	            ex.printStackTrace();
	        } finally {
	            if (io != null) {
	                try {
	                    io.close();
	                } catch (Exception e) {
	                    e.printStackTrace();
	                }
	            }
	        }

	    }
	 
	 private void start() {
	        try {
	            ServerSocket serverSocket = new ServerSocket(port);
	            System.out.println("Tomcat 服务已启动,地址:localhost ,端口:" + port);
	            this.init();
	            //持续监听
	            do {
	                Socket socket = serverSocket.accept();
	                System.out.println(socket);
	                //处理任务
	                Thread thread = new SocketProcess(socket);
	                
	                thread.start();
	            } while (true);
	                

	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	 
	 public static void main(String[] args) {
		 Mytomcat tomcat = new Mytomcat();
		 tomcat.start();
		 
	}
	 
}

UtilsXml:

import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class UtilsXml {
	//定义解析器和文档对象
	public SAXReader saxReader;
    public Document document;

    public  UtilsXml(String path){
        //获取解析器
        saxReader = new SAXReader();
        try {
            //获取文档对象
            document = saxReader.read(path);
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 根据节点名称获取内容
     * @param name 节点名称
     * @return 节点内容
     */
    public String getElementText(String name){
        //定位根节点
        Element root = document.getRootElement();
        
        List<Element> mapp = root.elements("servlet-mapping");
        
        List<Element> servlet = root.elements("servlet");
        
        String serveltName = "";
        String classpath = "";
        
        for (Element e : mapp) {
//        	System.out.println(e.element("url-pattern").getText());
        	if(e.element("url-pattern").getText().equals(name)){
        		serveltName = e.element("servlet-name").getText();
        		break;
        	}
		}
        
        
        for (Element e : servlet) {
//        	System.out.println(e.element("servlet-name").getText());
        	if(e.element("servlet-name").getText().equals(serveltName)){
        		classpath = e.element("servlet-class").getText();
        		break;
        	}
		}

        return classpath;
//        //根据名称定位节点
//        Element element = root.element(name);
//        //返回节点内容
//        return element.getText();
    }
    
    /**
     * 获取节点下的所有节点
     * @param root
     * @param name
     * @return
     */
    public  List<Element> getNodes(String name){
    	 Element root = document.getRootElement();
    	 return root.elements(name);
    }
    
    public static void main(String[] args) {
    	UtilsXml xml = new UtilsXml(UtilsXml.class.getResource("/")+"web.xml");
    	//System.out.println(xml.getElementText("/myhtml.html"));
      
    	List<Element> list = xml.getNodes("servlet");
    	for (Element element : list) {
    		System.out.println(element.element("servlet-name").getText() );
    		System.out.println(element.element("servlet-class").getText() );
		}
    	
	}

Servelt 抽象类:

import com.siyuan.http.Request;
import com.siyuan.http.Response;

public abstract class Servelt {
	
	public void service(Request request, Response response) {

		//判断是调用doget 还是 dopost
        if ("get".equalsIgnoreCase(request.getMethod())) {
            this.doGet(request, response);
        } else {
            this.doPost(request, response);
        }


    }

    public abstract void doGet(Request request, Response response);

    public abstract void doPost(Request request, Response response);
}

第一个servlet :

import com.siyuan.http.Request;
import com.siyuan.http.Response;

public class MyfisrtServlet extends Servelt {

	@Override
	public void doGet(Request request, Response response) {
		System.out.println("进入了我的第一个servlet");
		response.setWirte("进入了第一个servlet");
	}

	@Override
	public void doPost(Request request, Response response) {
	
		
	}

}

第二个servlet:

import com.siyuan.http.Request;
import com.siyuan.http.Response;

public class ScoendServlet extends Servelt{

	@Override
	public void doGet(Request request, Response response) {
	  
		System.out.println("进入了我的第二个servlet");
		response.setWirte("进入了第二个servlet");
	}

	@Override
	public void doPost(Request request, Response response) {
		// TODO Auto-generated method stub
		
	}

}

新建web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 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>myhtml.html</servlet-name>
    <servlet-class>com.siyuan.servlet.MyfisrtServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>myhtml.html</servlet-name>
    <url-pattern>/myhtml.html</url-pattern>
 </servlet-mapping>
 
 
 
  <servlet>
    <servlet-name>myhtml2.html</servlet-name>
    <servlet-class>com.siyuan.servlet.ScoendServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>myhtml2.html</servlet-name>
    <url-pattern>/myhtml2.html</url-pattern>
 </servlet-mapping>
 
 
  
</web-app>

运行效果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 自定义注解与常用设计模式

    注解分为:内置注解,自定义注解。内置注解就是JDK 自带的,而自定义注解则是自己定义的比如许多框架(spring) 用到的

    斯文的程序
  • Oracle 多表连接查询取最近一条记录

    2、 通过这个函数 select a.* row_number() over(partition by 分组的字段 order by 排序时间 desc) ...

    斯文的程序
  • Spring5 系统架构

    一,系统架构   Spring 总共大约有 20 个模块,由 1300 多个不同的文件构成。而这些组件被分别整合在核心容器 (Core Container...

    斯文的程序
  • 手写tomcat+servlet

    用户4478423
  • Java设计模式(七)----装饰模式

    装饰模式 一、概述 二、装饰模式的结构 三、具体案列 四、装饰模式与类继承的区别...

    汤高
  • 在C#中使用依赖注入-三层结构

    三层结构是服务端开发中最为基础的一种结构,也是作为简单项目最为常见的一种结构。本文件将对“如何在三层结构中使用依赖注入”进行介绍。

    newbe36524
  • 动态创建类

    用户6362579
  • SpringBoot应用篇之FactoryBean及代理实现SPI机制示例

    FactoryBean在Spring中算是一个比较有意思的存在了,虽然在日常的业务开发中,基本上不怎么会用到,但在某些场景下,如果用得好,却可以实现很多有意思的...

    小灰灰
  • 设计模式 | 装饰者模式及典型应用

    装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型...

    小旋锋
  • 【小家Spring】Spring MVC容器的web九大组件之---HandlerAdapter源码详解---HttpMessageConverter 消息转换器详解

    本文介绍Spring MVC中的一个极其重要的组件:HttpMessageConverter消息转换器。

    BAT的乌托邦

扫码关注云+社区

领取腾讯云代金券