Notas de estudo JavaWeb 3: princípio de implementação do Tomcat

Vá para a frente: algumas das fotos foram tiradas do servlet do professor Ma Bingbing e
das notas de aula jsp.
Link do vídeo: https://www.bilibili.com/video/BV1cV411H7RY?p=1

** Princípio de funcionamento do Tomcat:
*
Diagrama de interação cliente-servidor
Processo de interação:
o cliente envia uma solicitação ao servidor, a solicitação do Tomcat recebe a solicitação e a envia ao objeto de solicitação de serviço. O objeto de solicitação seleciona um programa de miniaplicativo escrito antecipadamente para processar a solicitação e responde para concluir o serviço. Nesse processo, o contêiner do servidor web possui muitos miniaplicativos. Como o serviço sabe qual deles chamar? O applet está equipado com o processamento de solicitações. Mas o que deve ser tratado no início é encapsular os objetos de solicitação e resposta.
Formato da mensagem de solicitação:
Solicitar formato de mensagem

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

Aqui está um simples encapsulamento de solicitação, apenas o princípio da simulação.
Interpretação de código: a transmissão de dados ainda é uma transmissão de fluxo. O objeto de solicitação recebe o fluxo de entrada e configura um buffer para dividi-lo e analisá-lo em dados do tipo string para processamento.
formato de resposta

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

Interpretação do código: a resposta converte a string processada em uma resposta de fluxo, preste atenção em "anexar ("\r\n")". Após o encapsulamento,
descobrimos: Na verdade, este processo é o processo de solicitação (solicitação) e entrega ( resposta). Qual miniaplicativo você deseja solicitar (requesturl)? Podemos fazer um relacionamento de mapeamento entre cada requesturl e a classe de encapsulamento do miniaplicativo. Como cada miniaplicativo tem o mesmo método, mas o corpo do método é diferente, então podemos usar uma classe abstrata para permitir que todos herdem ou usem interfaces para padronizá-los.

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

}

Mapeando relações:

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

	
}

De volta à Figura 1:

encapsulamos serviço, interface e miniaplicativo, mas ainda falta interação de rede e interação serviço-miniaplicativo. O servidor conclui esse processo.

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

Interpretação de código: método estático parâmetros do método startserver: número da porta. Passe os parâmetros para o soquete do servidor (serversocket), e o ferrolho da porta (loop infinito) implementa um serviço longo. O servidor recebe a solicitação e a atribui ao soquete para processamento. O soquete obtém o fluxo, passa e cria MyRequest e MyRespond objetos. O código-chave: String clazzName = new MyMapping().getMapping().get(request.getRequestUrl()); Obtenha o miniaplicativo chamado pelo mapeamento de URL da solicitação e, em seguida, use o mecanismo de reflexão para criar o objeto do miniaplicativo e polimorficamente chame o método doget/dopost para processar a solicitação e responder.
Após a execução, o navegador solicita os resultados:

Mas ainda existem alguns problemas, como multithreading e alta simultaneidade, etc., que serão implementados posteriormente.

Acho que você gosta

Origin blog.csdn.net/qq_52605986/article/details/116995860
Recomendado
Clasificación