通过miniTomcat理解tomcat运行机制加源码

miniTomcat运行机制

处理请求的request

import java.io.IOException;
import java.io.InputStream;

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

    public MyRequest(InputStream inputStream) throws IOException{
        String httpRequest="";
        byte[] httpRequestBytes=new byte[1024];
        int length=0;
        if ((length=inputStream.read(httpRequestBytes))>0){
            httpRequest=new String (httpRequestBytes,0,length);
        }


//         请求头的内容
//		HTTP请求协议
//         GET /favicon.icoHTTP/1.1
//         Accept: */*
//        Accept-Encoding :gzip,deflate
//        User-Agent:Mozilla/5.0 (Windows NT 6.1;WOW64;Trident/7.0;rv:11.0) like Ge
//        Host: localhost:8080
//        Connection: Keep-Alive

        String httpHead=httpRequest.split("\n")[0];
        url=httpHead.split("\\s")[1];
        method=httpHead.split("\\s")[0];
        System.out.println(this);
    }

    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;
    }
}

url :除上下文外的mapping(例如:http://localhost:8080/girl)中的‘/girl’
method:请求服务器的方法,常用的为:GET,POST,DELTE等
通过url的值就和web.xml中的中的值等效

服务器响应response

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

public class MyResponse {

    private OutputStream outputStream;

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

    public void write(String content) throws IOException{
        /*  HTTP 响应协议
        HTTP/1.1 200 OK
        Content -Type: text/html
        <html><body></body></html>
        */
        StringBuffer httpResponse=new StringBuffer();
        httpResponse.append("HTTP/1.1 200 Ok\n")
                .append("Content -Type: text/html\n")
                .append("\r\n")
                .append("<html><body>")
                .append(content)
                .append("</body></html>");

        outputStream.write(httpResponse.toString().getBytes());
        outputStream.close();
    }
}

处理请求的servlet

import javax.xml.ws.Response;

public abstract class MyServlet {

    public abstract void doGet(MyRequest myRequest,MyResponse myResponse);

    public abstract void doPost(MyRequest myRequest,MyResponse myResponse);

    public void service(MyRequest myRequest,MyResponse myResponse){
        if (myRequest.getMethod().equalsIgnoreCase("POST")){
            doPost(myRequest,myResponse);
        }else if (myRequest.getMethod().equalsIgnoreCase("GET")){
            doGet(myRequest,myResponse);
        }
    }
}

根据请求的方式,判断调用的方法

mapping文件

public class ServletMapping {

    private String servletName;
    private String url;
    private String clazz;

    public ServletMapping(String servletName,String url,String clazz){
        this.servletName=servletName;
        this.url=url;
        this.clazz=clazz;
    }

    public ServletMapping(){

    }

    public String getServletName() {
        return servletName;
    }

    public void setServletName(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;
    }
}

用来存放类的名称与类的全路径,映射的关系

存放所有类与映射的关系

import java.util.ArrayList;
import java.util.List;

public class ServletMappingConfig {

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

    static {
        servletMappingList.add(new ServletMapping("findGirl","/girl","mytomcat.FindGirlServlet"));
        servletMappingList.add(new ServletMapping("helloWorld","/world","mytomcat.HelloWorldServlet"));

    }
}

这个相当于一个容器,存放所有的映射关系

测试类

import java.io.IOException;

public class HelloWorldServlet extends MyServlet {

    public void doGet(MyRequest myRequest,MyResponse myResponse){
        try{
            myResponse.write("get world...");
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void doPost(MyRequest myRequest,MyResponse myResponse){

        try{
            myResponse.write("post world...");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
import java.io.IOException;

public class FindGirlServlet extends MyServlet {

    public void doGet(MyRequest myRequest,MyResponse myResponse){

        try{
            myResponse.write("get girl...");
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void doPost(MyRequest myRequest,MyResponse myResponse){

        try{
            myResponse.write("post girl");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

tomcat容器

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

public class MyTomcat {

    private int port = 8080;

    private Map<String,String>  urlServletMap = new HashMap<String, String>();

    public MyTomcat(int port){
        this.port = port;
    }
    public void start(){
        //初始化 url 与对应处理的servlet的关系
        initServletMapping();
        ServerSocket serverSocket=null;
        try{
            serverSocket=new ServerSocket(port);
            System.out.println("MyTomcat is start");

            while (true){

                Socket socket=serverSocket.accept();//tomcat运行后
                InputStream inputStream=socket.getInputStream();
                OutputStream outputStream=socket.getOutputStream();

                MyRequest myRequest=new MyRequest(inputStream);
                MyResponse myResponse=new MyResponse(outputStream);

                //请求分发
                dispatch(myRequest,myResponse);

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

    private void initServletMapping(){
        for (ServletMapping servletMapping:ServletMappingConfig.servletMappingList){

            urlServletMap.put(servletMapping.getUrl(),servletMapping.getClazz());
        }
    }

    private void dispatch(MyRequest myRequest,MyResponse myResponse){

    String clazz=urlServletMap.get(myRequest.getUrl());

        //反射
        try{
            Class<MyServlet> myServletClass=(Class<MyServlet>)Class.forName(clazz);
            MyServlet myServlet=myServletClass.newInstance();

            myServlet.service(myRequest,myResponse);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args){

        new MyTomcat(8080).start();
    }
}

根据手写tomcat分析tomcat运行的全过程

tomcat启动操作

1.指定端口后,执行start()方法
1.1 将类与映射的关系放入容器,相当于web项目中,加载web.xml文件
1.2 启动对端口的监听程序
2.客户端请求的处理
2.1 生成request和response
2.2使用request,response进行请求的分发
2.3通过请求的url得到要执行的类的路径
2.4利用反射创建servlet,执行service方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值