学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat

2019-05-09   19:28:42

注:项目(MyEclipse)创建的时候选择:Web Service Project

第一步 对Tomcat工作流程进行分析

第二步 对其项目进行全局的把关

首先看看Project(FirstTomcat)的目录结构

|-FirstTomcat

|——src

|   |-org.mrzhangxd.com

|     |-FirstRequest.java

|     |-FirstResponse.java

|     |-FirstServlet.java

|     |-FirstTomcat.java

|     |-FirstServletMapping.java

|     |_FirstServletMappingConfig.java

|   |-JRE System Library[JavaSE-x.y]

|   |-JAXB x.y.z Libraries

|   |-JavaEE x.y Generic Library

|   |-JSTL x.y.z Library

|   |-JAX-RS x.y Libraries(Project Jersey x.y)

|___|_WebRoot

第三步 代码实现

处理请求:

    1. 创建一个request对象并填充那些有可能被所引用的Servlet使用的信息,如参数,头部、cookies、查询字符串等。
    2. 创建一个response对象,所引用的servlet使用它来给客户端发送响应。
    3. 调用servlet的service方法,并传入request和response对象。这里servlet会从request对象取值,给response写值。
    4. 根据servlet返回的response生成相应的HTTP响应报文。

接下来一一实现

请求:FirstRequest.java

package org.mrzhangxd.com;

import java.io.InputStream;

/**

 *

 * @author mrzhangxd

 *

 */

public class FirstRequest {

        //请求路径

        private String url;

        //请求方法

        private String method;

        public FirstRequest(InputStream inputStream)throws Exception{

            String httpRequest = "";

            byte[] httpRequestBytes = new byte[1024];

            int length = 0;

            if((length = inputStream.read(httpRequestBytes))>0){

                httpRequest = new String(httpRequestBytes,0,length);

            }

            //HTTP请求协议:首行的内容依次为:请求方法、请求路径以及请求协议及其对应的版本号

            //GET    /index    /HTTP/1.1

            String httpHead = httpRequest.split("\n")[0];//取出HTTP协议的首行

            System.out.println(httpHead);

            method = httpHead.split("\\s")[0];//按照空格进行分割,第一个请求方法

           

            url = httpHead.split("\\s")[1];//按照空格进行分割,第二个是路径

            System.out.println(this.toString());

        }

       

        public String getUrl() {

            return url;

        }

        public void setUrl(String url) {

            this.url = url;

        }

        public String getMethod() {

            return method;

        }

        public void setMethod(String method) {

            this.method = method;

        }

        public String toString(){

            return "MyRequest[url = "+url+",method = "+method+"]";

           

        }

}

回应:FirstResponse.java

package org.mrzhangxd.com;

import java.io.IOException;

import java.io.OutputStream;

/**

 *

 * @author mrzhangxd

 *

 */

public class FirstResponse {

    private  OutputStream outputStream;

    public FirstResponse(OutputStream outputStream){

        this.outputStream = outputStream;

    }

    //将文本转换为字节流

    public void write(String content)throws IOException{

        StringBuffer httpResponse = new StringBuffer();

        httpResponse.append("HTTP/1.1 200 OK\n")

        .append("Content-Type;text/html\n")

        .append("\r\n")

        .append("<html><link rel = \"icon\"href = \"data:;base64,=\">")

        .append(content)//将页面内容写入

        .append("</body></html>")

        .append("");

        outputStream.write(httpResponse.toString().getBytes());//将文本转换为字节码

        outputStream.close();

    }

}

Servlet请求处理基类:FirstServlet.java

package org.mrzhangxd.com;

/**

 *

 * @author mrzhangxd

 *

 */

public abstract class FirstServlet {

    public void servlet(FirstRequest firstRequest,FirstResponse firstResponse){

        if(firstRequest.getMethod().equalsIgnoreCase("POST")){

            doPost(firstRequest,firstResponse);

        }else if(firstRequest.getMethod().equalsIgnoreCase("GET")){

            doGet(firstRequest,firstResponse);

        }

    }

    private void doGet(FirstRequest firstRequest, FirstResponse firstResponse) {

        // TODO Auto-generated method stub

    }

    private void doPost(FirstRequest firstRequest, FirstResponse firstResponse) {

        // TODO Auto-generated method stub

    }

    public void service(FirstRequest firstRequest, FirstResponse firstResponse) {

        // TODO Auto-generated method stub

    }

}

下一步servlet配置:FirstServletMapping.java

package org.mrzhangxd.com;

 

/**

 *

 * @author mrzhangxd

 *

 */

public class FirstServletMapping {

    private String servletName;

    private String url;

    private String clazz;

   

    public FirstServletMapping(String servletName, String url, String clazz) {

        super();

        this.servletName = servletName;

        this.url = url;

        this.clazz = clazz;

    }

   

    public String getServletName() {

        return servletName;

    }

   

    public void setServeletName(String servletName) {

        this.servletName = servletName;

    }

   

    public String getUrl() {

        return url;

    }

   

    public void setUrl(String url) {

        this.url = url;

    }

   

    public String getClazz() {

        return clazz;

    }

   

    public void setClazz(String clazz) {

        this.clazz = clazz;

    }

}

其他配置:FirstServletMappingConfig.java

package org.mrzhangxd.com;

import java.util.ArrayList;

import java.util.List;

/**

 *

 * @author mrzhangxd

 *

 */

public class FirstServletMappingConfig {

    public static List<FirstServletMapping> servletMappingList = new ArrayList<>();

    static {

        servletMappingList.add(new FirstServletMapping("index", "/index", "firstTomcat.test.IndexServlet"));

        servletMappingList.add(new FirstServletMapping("firstblog", "/firstblog", "firstTomcat.test.MyBlog"));

    }

}

核心处理类:FirstTomcat.java,处理流程如下:

1)   提供Socket服务

2)   封装请求/响应对象

3)   将不同的请求映射到具体的Servlet处理

这里重点说的是,要利用 ServerSocket 通过服务器上的端口通信 以及 accpt方法一直等待客户端的请求

package org.mrzhangxd.com;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.HashMap;

import java.util.Map;

/**

 *

 * @author mrzhangxd

 *

 */

public class FirstTomcat {

    private Integer port = 8080;     //定义8080端口    

    private Map<String, String> urlServletMapping = new HashMap<>();    //存储url和对应的类

    public FirstTomcat(Integer port) {

        super();

        this.port = port;

    } 

    @SuppressWarnings("resource")

    public void start() {

        initServletMapping();      

        try {

            ServerSocket serverSocket = null;     //实例化一个 ServerSocket 对象,表示通过服务器上的端口通信

            serverSocket = new ServerSocket(port);  

            System.out.println("MyTomcat is starting...");

            while(true) {

            Socket socket = serverSocket.accept();     //服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口

            InputStream inputStream = socket.getInputStream();

            OutputStream outputStream = socket.getOutputStream(); 

            FirstRequest myRequest = new FirstRequest(inputStream);

            FirstResponse myResponse = new FirstResponse (outputStream);   

            dispatch(myRequest, myResponse);       

            socket.close();               

            }

        }catch(Exception e) {

            e.printStackTrace();

        }

    }

    //初始化映射

    public void initServletMapping() {

        for(FirstServletMapping servletMapping : FirstServletMappingConfig.servletMappingList) {

            urlServletMapping.put(servletMapping.getUrl(), servletMapping.getClazz());

        }

        }  

    //分发请求

    @SuppressWarnings("unchecked")

    public void dispatch(FirstRequest firstRequest, FirstResponse firstResponse) {

        String clazz = urlServletMapping.get(firstRequest.getUrl());        

        try {

            Class<FirstServlet> firstServletClass = (Class<FirstServlet>)Class.forName(clazz);

            FirstServlet firstservlet = firstServletClass.newInstance();

            firstservlet.service(firstRequest, firstResponse);

        }catch(ClassNotFoundException e) {

            e.printStackTrace();

        }catch(InstantiationException e) {

            e.printStackTrace();

        }catch(IllegalAccessException e) {

            e.printStackTrace();

        }

        }    

        public static void main(String[] args) {

            FirstTomcat myTomcat = new FirstTomcat(8080);

            myTomcat.start();

        }

}

测试类按照上面类里的注释自己解决,测试结果略。

注:

编码格式、注释都参考《代码整洁之道》

学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat的更多相关文章

  1. Tomcat与Servlet工作流程

    什么是Tomcat? Tomcatserver是一个免费的开放源码的Web 应用server,属于轻量级应用server. 什么是Servlet? Servlet是在server上执行的小程序.,说白 ...

  2. Redux学习之我对于其工作流程的理解和实践

      目录 1 工作流程图 2 各部位职责 3 Demo   1 工作流程图   2 各部位职责 我在理解这个流程图的时候,采用的是一种容易记住的办法,并且贴切实际工作职责. 我们可以把整个Redux工 ...

  3. spring+hibernate工作流程文件名理解

    reg.jsp regsuccess.jsp User.java UserDAO.java UserDAOImpl.java User.hbm.xml Reg.java RegImpl.java Re ...

  4. 【Git项目管理】分布式 Git - 分布式工作流程

    分布式 Git - 分布式工作流程 你现在拥有了一个远程 Git 版本库,能为所有开发者共享代码提供服务,在一个本地工作流程下,你也已经熟悉了基本 Git 命令.你现在可以学习如何利用 Git 提供的 ...

  5. =面试题:java面试基本方向 背1 有用 项目二技术学完再看

    一.Java基础 1. 集合框架A)集合中泛型优点? 将运行期的ClaasCastException 转到编译期异常.  泛型还提供通配符 1)HashMap---允许一个键为null,允许多个值为n ...

  6. 零基础学完Python的7大就业方向,哪个赚钱多?

    “ 我想学 Python,但是学完 Python 后都能干啥 ?” “ 现在学 Python,哪个方向最简单?哪个方向最吃香 ?” “ …… ” 相信不少 Python 的初学者,都会遇到上面的这些问 ...

  7. Tomcat内部结构、工作原理、工作模式和运行模式

    TOMCAT的内部结构 Tomcat是一个基于组件的服务器,它的构成组件都是可配置的,其中最外层的是Catalina servlet容器,其他组件按照一定的格式要求配置在这个顶层容器中.Tomcat的 ...

  8. 手动实现简单的tomcat服务器

    手动实现tomcat服务器的流程: 分析具体的实现步骤: 1,浏览器和后端服务如何实现通信,首先传输的数据要遵循http协议,通过tcp也就是我们常说的套接字编程来实现,具体的底层数据传输肯定就是我们 ...

  9. 【Tomcat】Servlet 工作原理解析

    Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.因而掌握 Servlet 的工作原理是成为一名合格的 Java Web 技术开发人员的 ...

随机推荐

  1. Form key length limit 2048 exceeded ,提交数据时,数据的键过长 或者是上传文件过大

    在ASP.NET Core MVC中,文件的key 默认最大为2048,文件上传的最大上传文件默认为20MB,如果我们想上传一些比较大的文件,就不知道怎么去设置了,没有了Web.Config我们应该如 ...

  2. C#使用HtmlAgilityPack快速爬虫

    HtmlAgilityPack真是一把网抓利器,可以迅速地从网页抓到想要的文本或数据,使用起来十分方便,引用时在NuGet安装添加并在头部引用using HtmlAgilityPack;即可. 针对网 ...

  3. 基于【 centos7】一 || 安装ELK

    一.安装jdk 上传安装包并解压:tar -zxvf ... 配置环境变量: 在配置文件中添加如下配置信息:vi /etc/profile export JAVA_HOME=/usr/local/jd ...

  4. 关于reduce

    arr.reduce( callback,[initialValue]) reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素 callback (执行数组中每个值 ...

  5. python日志实时分析

    python随着人工智能的发展,越来越火热.但其实python在运维测试方面,也是一把利器. 最近就碰到了个需求,就顺手写了个python程序.用惯了go,不过发现python好像更简单点 :-) 涉 ...

  6. Array + two points leetcode.15-3Sum

    题面 Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Fi ...

  7. ant design pro超详细入门教程

    1.Ant Design Pro 初了解 说到ant design pro,得先了解一下ant design是个什么东西?ant design蚂蚁金服基于react打造的一个服务于企业级产品的UI框架 ...

  8. Flutter——Wrap组件(流式布局)

    Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Row 表现几乎一致.但 Row 与 Column 都是单行单列的,Wrap 则突破了这个限制,mainA ...

  9. 4.Hbase Shell 命令

    Hbase提供了一个shell的终端给用户交互:#$HBASE_HOME/bin/hbase shell,执行quit命令可以退出命令行 2.使用Hbase Shelll 命令操作: 名称 命令表达式 ...

  10. [Python] Codecombat攻略 远边的森林 Forest (1-40关)

    首页:https://cn.codecombat.com/play语言:Python 第二界面:远边的森林Forest(40关)时间:2-6小时内容:if/else.关系操作符.对象属性.处理输入网页 ...