JavaWeb study notes 3: tomcat implementation principle

Hit the front: Some of the pictures are taken from teacher Ma Bingbing’s servlet and jsp
lecture notes.
Video link: https://www.bilibili.com/video/BV1cV411H7RY?p=1

** Tomcat operating principle:
*
Client-server interaction diagram
Interaction process:
the client sends a request to the server, tomcat request receives the request, and submits it to the service request object. The request object selects an applet program written in advance to process the request, and responds to complete the service. In this process, the webserver container has many applets. How does the service know which one to call? The applet is equipped with the processing of requests. But what must be dealt with at the beginning is to encapsulate the request and response objects.
Request message format:
Request message format

package com.msb;

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

public class MyRequest {
    
    
	private String requestMethod;
	private String requestUrl;
	public MyRequest(InputStream inputStream) throws IOException {
    
    
		//创建缓冲区
		byte[] buffer=new byte[1024];
		int len=0;
		String str=null;
		if((len=inputStream.read(buffer))>0) {
    
    
			str=new String(buffer,0,len);
		}
		String data=str.split("\n")[0];
		String[] params=data.split(" ");
		this.requestMethod=params[0];
		this.requestUrl=params[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;
	}
	
}

Here is a simple encapsulation of request, just the simulation principle.
Code interpretation: Data transmission is still stream transmission. The request object receives the inputstream stream, and sets up a buffer to split and parse it into string type data for processing.
response format

package com.msb;

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

public class MyResponse {
    
    
	private OutputStream outputStream;
	public MyResponse(OutputStream outputStream) {
    
    
		this.outputStream=outputStream;
	}
	public void write(String str) throws IOException {
    
    
		StringBuilder builder = new StringBuilder();
		builder.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(builder.toString().getBytes());
		
	}
}

Code interpretation: response converts the processed string into a stream response, pay attention to "append ("\r\n")". After encapsulation, we
find: In fact, this process is the process of request (request) and giving (response). Which applet do you want to request (requesturl)? We can make a mapping relationship between each requesturl and the applet encapsulation class. Because each applet has the same method but the method body is different, so we can use an abstract class to let They all inherit, or use interfaces to standardize them.

package com.msb;

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);
	public abstract void doPost(MyRequest request,MyResponse response);
	
	
	//根据请求判断调用哪个方法
	public void service(MyRequest request,MyResponse response) {
    
    
		if(METHOD_GET.equals(request.getRequestMethod())) {
    
    
			doGet(request,response);
		}else if(METHOD_POST.equals(response)) {
    
    doPost(request,response);}
	}
}
package com.msb;

import java.io.IOException;

public class MyServlet extends MyHttpServlet {
    
    

	@Override
	public void doGet(MyRequest request, MyResponse response) {
    
    
		try {
    
    
			response.write("doget:MyServlet");
		} catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public void doPost(MyRequest request, MyResponse response) {
    
    
		try {
    
    
			response.write("doPost:MyServlet");
		} catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Mapping relations:

package com.msb;

import java.util.HashMap;

public class MyMapping {
    
    
	public static HashMap<String,String> mapping=new HashMap<String,String>();
	
	static {
    
    
		mapping.put("/MyTomCat", "com.msb.MyServlet");
		
	}

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

	
}

Back to Figure 1:

We have encapsulated service, interface, and applet, but we still lack network interaction and service-applet interaction. The server completes this process.

package com.msb;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

//定义服务端的接收程序,接收socket请求

public class MyServer {
    
    

	//定义服务端的接受程序,接受socket请求
	
	@SuppressWarnings("deprecation")
	public static void startServer(int port) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
    
    
		ServerSocket serverSocket = new ServerSocket(port);
		Socket socket=null;
		while(true) {
    
    
			socket=serverSocket.accept();
			InputStream inputStream = socket.getInputStream();
			OutputStream outputStream = socket.getOutputStream();
			MyRequest request=new MyRequest(inputStream);
			MyResponse response = new MyResponse(outputStream);
			String clazzName = new MyMapping().getMapping().get(request.getRequestUrl());
			if(clazzName!=null) {
    
    
				Class<? extends MyHttpServlet> clazz = (Class<? extends MyHttpServlet>)Class.forName(clazzName);
				MyHttpServlet newInstance = clazz.newInstance();
				newInstance.service(request, response);
				
			}
		}
		
	}
	public static void main(String[] args) {
    
    
		try {
    
    
			startServer(1775);
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Code interpretation: Static method startserver method parameters: port number. Pass the parameters to the server socket (serversocket), and the iron door bolt (infinite loop) implements long service. The server receives the request and assigns it to the socket for processing. The socket obtains the stream, passes and creates MyRequest and MyRespond objects. The key code: String clazzName = new MyMapping().getMapping().get(request.getRequestUrl()); Get the applet called by the request url mapping, then use the reflection mechanism to create the applet object, and polymorphically call the doget/dopost method to process the request and respond.
After running, the browser requests the results:

But there are still some problems, such as multi-threading and high concurrency, etc., which will be implemented later.

Guess you like

Origin blog.csdn.net/qq_52605986/article/details/116995860