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:
*
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:
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.
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.