栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

模拟一个简单的tomcat

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模拟一个简单的tomcat

文章目录
    • 简单处理
    • 每个请求一个线程
    • 模拟tomcat
    • 参考

简单处理
// 客户端和服务器的通信,说到底就是两个数据的传输,
// 客户端发送inputStream给服务器,服务器回复
// outputStream给客户端。
public class TomcatServerV1 {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true) {//一直监听,直到受到停止的命令
            Socket socket = null;
            try {
                socket = serverSocket.accept();//如果没有请求,会一直hold在这里等待,有客户端请求的时候才会继续往下执行
                // log
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取输入流(请求)
                StringBuilder stringBuilder = new StringBuilder();
                String line = null;
                while ((line = bufferedReader.readLine()) != null && !line.equals("")) {//得到请求的内容,注意这里作两个判断非空和""都要,只判断null会有问题
                    stringBuilder.append(line).append("
"); } String result = stringBuilder.toString(); System.out.println(result); // echo PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);//这里第二个参数表示自动刷新缓存 printWriter.println("HTTP/1.1 200 OK"); printWriter.println("Content-Type:text/html;charset=utf-8"); printWriter.println(); printWriter.println("你刚才发送的请求数据是:
"); printWriter.write(result);//将日志输出到浏览器 printWriter.println(""); // release printWriter.close(); bufferedReader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }

每个请求一个线程
class RequestHandler implements Runnable{
    private Socket socket;

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

    @Override
    public void run() {
        // log
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取输入流(请求)
            StringBuilder stringBuilder = new StringBuilder();
            String line = null;
            while ((line = bufferedReader.readLine()) != null && !line.equals("")) {
                stringBuilder.append(line).append("
"); } String result = stringBuilder.toString(); System.out.println(result); // echo PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);//这里第二个参数表示自动刷新缓存 printWriter.println("HTTP/1.1 200 OK"); printWriter.println("Content-Type:text/html;charset=utf-8"); printWriter.println(); printWriter.println("你刚才发送的请求数据是:
"); printWriter.write(result);//将日志输出到浏览器 printWriter.println(""); // release printWriter.close(); bufferedReader.close(); socket.close(); }catch (Exception e) { e.printStackTrace(); } } } public class TomcatServerV2 { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); while (true) {//一直监听,直到受到停止的命令 Socket socket = null; socket = serverSocket.accept();//如果没有请求,会一直hold在这里等待,有客户端请求的时候才会继续往下执行 RequestHandler requestHandler = new RequestHandler(socket); new Thread(requestHandler).start(); } } }
模拟tomcat

正如前面的博客:Servlet笔记中记录:

首先建一个MyServlet接口,然后创建一个抽象类MyHttpServlet继承接口,最后建一个UserServlet实现具体的doGet,doPost等方法。

pom依赖添加servlet和dom4j。DOM4J是dom4j.org出品的一个开源XML解析包。

项目目录:

原理图:

Request.java

package cn.orzlinux.Bean.mytomcat.http;

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

public class Request {
    // 如/usr
    private String uri;
    // 请求方法
    private String method;
    public Request(InputStream inputStream) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader((inputStream)));
            //取HTTP请求响应的第一行,GET /user HTTP/1.1,按空格隔开
            String[] data = reader.readLine().split(" ");
            this.uri = data[1];
            this.method = data[0];
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public String getMethod() {
        return method;
    }

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

response

package cn.orzlinux.Bean.mytomcat.http;

import java.io.OutputStream;

public class Response {
    public OutputStream outputStream;

    public static final String responsebody="HTTP/1.1 200+rn"+"Content-Type:text/html+rn"
            +"rn";
    public Response(OutputStream outputStream){
        this.outputStream=outputStream;
    }
}

MyServlet

package cn.orzlinux.Bean.mytomcat.servlet;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response;

public interface MyServlet {
    void init() throws Exception;
    void service(Request request, Response response) throws Exception;
    void destroy();
}

MyHttpServlet

package cn.orzlinux.Bean.mytomcat.servlet;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response;

public abstract class MyHttpServlet implements MyServlet {
    public void init() throws Exception {

    }

    public void service(Request request, Response response) throws Exception {
        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);


    public void destroy() {

    }
}

userServlet

package cn.orzlinux.Bean.mytomcat.servlet;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response;

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

public class UserServlet extends MyHttpServlet {
    public void doGet(Request request, Response response) {
        System.out.println("doget");
        this.doPost(request,response);
    }

    public void doPost(Request request, Response response){
        OutputStream outputStream = response.outputStream;
        String result = Response.responsebody+"user handle successful";
        try {
            outputStream.write(result.getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

RequestHandler

package cn.orzlinux.Bean.mytomcat.socket;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response;
import cn.orzlinux.Bean.mytomcat.servlet.MyHttpServlet;

import java.io.*;
import java.net.Socket;

public class RequestHandler implements Runnable{
    private Socket socket;

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


    public void run() {
        // log
        try {
            Request request = new Request(socket.getInputStream());
            Response response = new Response(socket.getOutputStream());
            String uri = request.getUri();
            System.out.println(uri);

            String servletName = TomcatServerV3.urlmapping.get(uri);
            MyHttpServlet servlet = TomcatServerV3.servletMapping.get(servletName);

            if(servlet!=null) {
                servlet.service(request,response);
            }else{
                String resp=Response.responsebody+"can not find servlet";
                OutputStream outputStream=socket.getOutputStream();
                System.out.println(resp);
                outputStream.write(resp.getBytes());
                outputStream.flush();
                outputStream.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

TomcatServerV3

package cn.orzlinux.Bean.mytomcat.socket;


import cn.orzlinux.Bean.mytomcat.servlet.MyHttpServlet;
import cn.orzlinux.Bean.mytomcat.socket.RequestHandler;
import org.dom4j.document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;

public class TomcatServerV3 {
    public static final int port = 8080;
    // 定义mytomcat.xml中的两个映射
    public static final HashMap servletMapping = new HashMap();

    public static final HashMap urlmapping=new HashMap();

    public static void main(String[] args) throws IOException {
        TomcatServerV3 tomcatServerV3 = new TomcatServerV3();
        tomcatServerV3.init();
        tomcatServerV3.run();

    }

    // 初始化,加载xml里面的servlet信息
    private void init() {
        try {
            String path = TomcatServerV3.class.getResource("/").getPath();
            SAXReader reader = new SAXReader();
            document document = reader.read(new File(path+"mytomcat.xml"));

            Element rootelement = document.getRootElement();
            List elements = rootelement.elements();
            for(Element element:elements) {
                if ("servlet".equalsIgnoreCase(element.getName())){
                    Element servletname=element.element("servlet-name");
                    Element servletclass=element.element("servlet-class");
                    System.out.println(servletname.getText()+"==>"+servletclass.getText());
                    //需要注意的是servletMapping映射的第二个参数,要通过反射的方式进行实例化
                    servletMapping.put(servletname.getText(),
                            (MyHttpServlet) Class.forName(servletclass.getText().trim()).newInstance());
                }else if ("servlet-mapping".equalsIgnoreCase(element.getName())){
                    Element servletname=element.element("servlet-name");
                    Element urlpattern=element.element("url-pattern");
                    System.out.println(servletname.getText()+"==>"+urlpattern.getText());
                    urlmapping.put(urlpattern.getText(),servletname.getText());
                }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void run() {
        ServerSocket serverSocket= null;
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("====服务启动====");
            while(!serverSocket.isClosed()){
                Socket socket=serverSocket.accept();
                RequestHandler requestHandler=new RequestHandler(socket);
                new Thread(requestHandler).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出:

userServlet==>cn.orzlinux.Bean.mytomcat.servlet.UserServlet
userServlet==>/user
====服务启动====
/
HTTP/1.1 200+
Content-Type:text/html+

can not find servlet
/user
doget

最后再回顾一下原理图:

参考

java基于Socket实现的一个简单的HTTP服务器

从零开始手写Tomcat,一文彻底搞懂Tomcat运行流程(附源码)

本文同步发布于orzlinux.cn

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/289564.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号