Understanding of handwritten tomcat content in the development of JSP+Servlet+Tomcat application of Mr. Ma soldier in station B

This article is used to understand the specific implementation of tomcat written by teachers

Introduction (negligible)

After learning the basics of java, I looked directly at this video. I looked at it very well in the front. I was blinded when I saw the teacher writing this tomcat. First, I spent two days to re learn the knowledge of IO flow (recommended station B is still the basics of java in Silicon Valley). I reviewed the knowledge of the network. Today, I finished typing the code, read the code carefully, debug step by step, and take out the variables in the process to understand the whole structure, Code attached

Video attached first https://www.bilibili.com/video/BV1z5411A7DL?p=11

01ServeLet Tomcat

Definition: a constant service running on the server
tomcat composition:
————The first is the two objects connected to the client for request and response,
These two objects are collectively referred to as server,
Access multiple applet s (i.e. ServeLet) through these two objects,
Implement interface classes in applet s to do specific things,
An interface class is a set of specifications, in which there are many methods to process data,
The server will implement each request according to the information request applet,
That's why they're collectively called servlet

tomcat

Follow the video and write Tomcat yourself
Based on TCP protocol. Socket socket
The first is to obtain the corresponding Socket object and the input / output stream of the Socket object after the ServerSocket is created
This input / output stream is materialized into two Request and Response classes,

Let's start with response

The object of response class is created by the output stream of Socket as the construction parameter. There is a class member variable OutputStream in the class,
In other words, OutputStream is the output stream of Socket, and its write operation will be directly transmitted,
So the response class has a write() method (the IO of byte stream and character stream are both read() and write() methods),
In the write() method, the tag content in the response body is changed according to the incoming String parameter. In addition, it is written in the standard HTTP response format

Again, request refers to processing other people's requests

The request class object is also created by the Socket input stream as the construction parameter,
Class has class member variable InputStream. This object has no method except constructor and read-write function
The main function is in the construction method. The whole class is to receive the information required in InputStream, analyze and then give server specific parameters -——
The case provides two information through its own class members

 //Request method GET/POST  
    private String requestMethod;  
//Request address resource location URL  
    private String requestUrl;   

Of these two messages
1 - the request method is used to pass HttpServerLet, the abstract father of all serverlets. The function will be discussed below
2-URL is used to give MAP to obtain the corresponding serveret class according to the URL (the obtained path is the path of the whole tomcat project),

The doubtful point here is how the Socket gets this path?

Next is the map class

As mentioned earlier, the second information that request brings us is URL,
Only one member variable in the map class is a HashMap, and the specific key value pair information is declared by static
In this way, when the server obtains the request, it can give the corresponding servlet (which will call response()) to respond
Of course, there is also a get method in the map, which is convenient for being called to obtain key values

ServeLet

There can be many servelets, which are the method classes selected by the map according to the URL in the request to return specific information as needed;
All servelets inherit an interface HttpServeLet (as will be mentioned below, abstract classes are actually used)
And ServeLet needs to rewrite two inheritance methods to realize the response when obtaining GET and POST requests
In this case, the response writing method is simply called to send a response,
The response comes from the parameters in the interface rewrite method

HttpServeLet

It is the inherited interface of all ServeLet mentioned above, but in fact, the teacher uses abstract classes,
Because the abstract class can define non abstract methods that can be fully inherited. Server() is provided to servelets for use,
This method is used to judge POST and GET requests. The parameters are request and response
Compare the return value of the GetrequestUrl() method in the request with the static constants "post" and "get" in the class
And directly execute the corresponding abstract method (the method rewritten by itself will be executed when the subclass is called)

Concrete implementation

First, create the ServerSocket object and obtain the Socket object through the ServerSocket object.
Then obtain OutputStream and InputStream through Socket object respectively
Then it is used to create Request object and Response object respectively
At this time, the URL in the Request is obtained through GetRequestUrl of the Request object,
Then get the corresponding class name of the requested ServerLet object through the map
Create objects with reflection by class name,
Call the Service method through the object (inherited from the parent class,)
Parameters are the request and response objects created above
That's all. I didn't understand the combination code and read it ten times

The code comments are incomplete, but the key output for understanding is retained

MyRequest code

package com.hajizu;

import java.io.InputStream;

/**
 * The request method in the input stream is obtained through the construction method whose parameter is the input stream
 */
public class MyRequest {
    //Request method GET/POST
    private String requestMethod;
    //Request address resource location URL
    private String requestUrl;
//    //Protocol version html1 one
//    private String protocolType;

    public MyRequest(InputStream i)throws Exception{
        byte[] bys = new byte[1024];
        int len=0;
        String str=null;
        if((len=i.read(bys))!=-1)
        {
            str = new String(bys,0,len);
        }
        String[] s = str.split("\n")[0].split(" ");
//        GET /mytomcat HTTP/1.1
//        Host: localhost:52777
//        Connection: keep-alive
//        Cache-Control: max-age=0
//        sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
//        sec-ch-ua-mobile: ?0
//        Upgrade-Insecure-Requests: 1
//        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
//        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
//Sec-Fetch-Site: none
//Sec-Fetch-Mode: navigate
//Sec-Fetch-User: ?1
//Sec-Fetch-Dest: document
//Accept-Encoding: gzip, deflate, br
//Accept-Language: zh-CN,zh;q=0.9
        this.requestMethod=s[0];
        this.requestUrl=s[1];
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestUrl() {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        this.requestUrl = requestUrl;
    }

//    public String getProtocolType() {
//        return protocolType;
//    }
//
//    public void setProtocolType(String protocolType) {
//        this.protocolType = protocolType;
//    }
}

MyResponse code

package com.hajizu;

import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

/**
 *Automatically output a string composed of a write function parameter and a fixed HTML message;
 */
public class MyResponse {
    private OutputStream outputStream;

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

    public void write(String str)throws Exception
    {
        StringBuilder sb = new StringBuilder();
        sb.append("HTTP/1.1 200 OK\n")
                .append("Content-Type:text/html\n")
                .append("\r\n")
                .append("<html>")
                .append("<body>")
                .append("<h1>"+str+"</h1>")
                .append("</body>")
                .append("</html>");
        this.outputStream.write(sb.toString().getBytes());
        this.outputStream.flush();
        this.outputStream.close();

    }

    public OutputStream getOutputStream() {
        return outputStream;
    }

    public void setOutputStream(OutputStream outputStream) {
        this.outputStream = outputStream;
    }


}

MyMapping code

package com.hajizu;

import java.util.HashMap;


/**
 * It is used to connect specific servers through a and b page tags
 */
public class MyMapping {
    public static HashMap<String,String> mapping =new HashMap<>();
    static{
        mapping.put("/mytomcat","com.hajizu.Myservlet");
    }

    public static HashMap<String, String> getMapping() {
        return mapping;
    }
}

ServeLet code

package com.hajizu;

/**
 * applet A specific class is a specific thing to do
 */
public class Myservlet extends MyHttpServlet{
    @Override
    public void doGet(MyRequest request, MyResponse response) throws Exception {
        response.write("xxkelaDSB");
    }

    @Override
    public void doPost(MyRequest request, MyResponse response) throws Exception {
        response.write("hds");
    }
}

Httpserverlet code

package com.hajizu;

/**
 * applet A specific class is a specific thing to do
 */
package com.hajizu;

/**
 * Abstract methods, similar to interfaces, are used to give servlet class service methods, and the service defines the execution contents of get and post
 */
public abstract class MyHttpServlet {
    public static final String METHOD_GET="GET";
    public static final String METHOD_POST="POST";
    public abstract void doGet(MyRequest request,MyResponse response) throws Exception;
    public abstract void doPost(MyRequest request,MyResponse response) throws Exception;

    public void service (MyRequest request,MyResponse response)throws Exception{
        if(METHOD_GET.equals(request.getRequestMethod())){
            doGet(request,response);
        }
        if(METHOD_POST.equals(request.getRequestMethod())){
            doPost(request,response);
        }

    }
}


Keywords: Java network Tomcat

Added by inVINCEable on Fri, 18 Feb 2022 13:38:25 +0200