一、tomcat基础
1.基础功能
提供Socket服务:实现对某些端口的监听,从而实现请求到来时,Tomcat可以感知到。同时该Socket服务也需要支持HTTP协议。
封装请求和响应:通过之前的介绍,我们知道在我们开发Servlet时,Web容器已经将Context、Request、Response替我们封装好了,可以直接使用。Tomcat作为一款Servlet容器,肯定要支持这项功能。
请求分发:一个Tomcat可以提供多个Web服务,那么Tomcat需要支持将不同的url分发到不同的应用,调用不同的Servlet。
2.通信过程
3.HTTP报文请求和响应示例
二、代码实现
1、Servlet接口
package com.lijiacheng;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @ClassName : MyServer //类名
* @Description : //描述
* @Author : 李嘉诚 //作者
* @Date: 2022-01-20 22:05 //日期
*/
public class MyServer {
public static void startServer(int port) throws Exception{
//定义服务器套接字
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 clazz=new MyMapping().getMapping().get(request.getRequestUrl());
if(clazz!=null){
Class<MyServlet> myServletClass=(Class<MyServlet>)Class.forName(clazz);
//根据myServletClass创建对象
MyServlet myServlet = myServletClass.newInstance();
myServlet.service(request,response);
}
}
}
public static void main(String[] args) {
try {
startServer(10086);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.lijiacheng;
import java.io.IOException;
/**
* @ClassName : MyHttpServlet //类名
* @Description : //描述
* @Author : 李嘉诚 //作者
* @Date: 2022-01-11 23:00 //日期
*/
public abstract class MyHttpServlet {
public static final String METHOD_GET="GET";
public static final String METHOD_POST="POST";
public abstract void doGET(MyRequest myRequest,MyResponse myResponse) throws IOException;
public abstract void doPOST(MyRequest myRequest,MyResponse myResponse) throws IOException;
public void service(MyRequest myRequest,MyResponse myResponse) throws IOException {
if(METHOD_GET.equals(myRequest.getRequestMethod())){
doGET(myRequest,myResponse);
}else if(METHOD_POST.equals(myRequest.getRequestMethod())){
doPOST(myRequest,myResponse);
}
}
}
2.Request\Response抽象
package com.lijiacheng;
import java.io.IOException;
import java.io.InputStream;
public class MyRequest {
private String requestMethod;
private String requestUrl;
public MyRequest(InputStream inputStream) throws Exception {
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=str.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;
}
}
package com.lijiacheng;
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")
.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());
this.outputStream.flush();
this.outputStream.close();
}
}
3.Servlet映射
package com.lijiacheng;
import java.util.HashMap;
public class MyMapping {
public static HashMap<String,String> mapping=new HashMap<String,String>();
static {
mapping.put("/mytomcat","com.lijiacheng.MyServlet");
}
public HashMap<String,String> getMapping(){
return mapping;
}
}
4.server实现
package com.lijiacheng;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @ClassName : MyServer //类名
* @Description : //描述
* @Author : 李嘉诚 //作者
* @Date: 2022-01-20 22:05 //日期
*/
public class MyServer {
public static void startServer(int port) throws Exception{
//定义服务器套接字
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 clazz=new MyMapping().getMapping().get(request.getRequestUrl());
if(clazz!=null){
Class<MyServlet> myServletClass=(Class<MyServlet>)Class.forName(clazz);
//根据myServletClass创建对象
MyServlet myServlet = myServletClass.newInstance();
myServlet.service(request,response);
}
}
}
public static void main(String[] args) {
try {
startServer(10086);
} catch (Exception e) {
e.printStackTrace();
}
}
}