前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手写tomcat+servlet

手写tomcat+servlet

作者头像
故久
发布2019-09-29 14:45:31
4270
发布2019-09-29 14:45:31
举报
文章被收录于专栏:故久故久

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

一、我们分两步第一步先实现手写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>

运行效果:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档