手写Tomcat之简单实现
封装Request对象
/**
* @author CJ
* @description 通过输入流,对HTTP协议进行解析,拿到了HTTP请求头的方法以及URL
* @create 2021-04-25
**/
public class Request {
private String url;
private String method;
//通过输入流,对HTTP协议进行解析,拿到了HTTP请求头的方法以及URL
public Request(InputStream inputStream) throws IOException {
String httpRequest = "";
byte[] bytes = new byte[1024];
int length = 0;
if ((length = inputStream.read(bytes)) > 0) {
httpRequest = new String(bytes, 0, length);
}
// GET /executeServlet HTTP/1.1
// Host: localhost:8888
// Connection: keep-alive
// Pragma: no-cache
// Cache-Control: no-cache
// sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
// sec-ch-ua-mobile: ?0
// DNT: 1
// Upgrade-Insecure-Requests: 1
// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 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,zh-TW;q=0.8
// Cookie: SSO-SESSIONID=88ad2e2270a3498ea896931be14df2b4
String httpHead = httpRequest.split("\n")[0];
// GET /executeServlet HTTP/1.1
url = httpHead.split("\\s")[1];
method = httpHead.split("\\s")[0];
System.out.println(this);
}
// setter() getter() toString()
}
封装Response对象
/**
* @author CJ
* @description 通过输出流,基于HTTP协议对响应内容进行输出
* @create 2021-04-25
**/
public class Response {
private OutputStream outputStream;
public Response(OutputStream outputStream) {
this.outputStream = outputStream;
}
/**
* HTTP响应协议 HTTP/1.1 200 ok
* HTTP响应内容类型 Content-Type: text/html
*
* @param content
* @throws IOException
*/
public void write(String content) throws IOException {
StringBuffer httpResponse = new StringBuffer();
httpResponse.append("HTTP/1.1 200 OK\n")
.append("Content-Type: text/html\n")
.append("\r\n")
.append("<html><body>")
.append(content)
.append("</body></html>");
outputStream.write(httpResponse.toString().getBytes());
outputStream.close();
}
}
自定义Servlet
/**
* @author CJ
* @description 自定义简单Servlet
* @create 2021-04-25
**/
public abstract class Servlet {
public abstract void doGet(Request request, Response response);
public abstract void doPost(Request request, Response response);
public void service(Request request, Response response) {
if (request.getMethod().equalsIgnoreCase("POST")) {
doPost(request, response);
} else if (request.getMethod().equalsIgnoreCase("GET")) {
doGet(request, response);
}
}
}
定义具体的Servlet实现
/**
* @author CJ
* @description 定义具体的Servlet实现
* @create 2021-04-25
**/
public class ExecuteServlet extends Servlet {
@Override
public void doGet(Request request, Response response) {
try {
response.write("execute get Servlet....");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doPost(Request request, Response response) {
try {
response.write("execute post Servlet....");
} catch (IOException e) {
e.printStackTrace();
}
}
}
定义Servlet映射
public class ServletMapping {
private String servletName;
private String url;
private String clazz;
public ServletMapping(String servletName, String url, String clazz) {
this.servletName = servletName;
this.url = url;
this.clazz = clazz;
}
// setter() getter() toString()
}
/**
* @author CJ
* @description Servlet映射关系配置,类似web.xml文件
* @create 2021-04-25
**/
public class ServletMappingConfig {
public static List<ServletMapping> servletMappingList = new ArrayList<ServletMapping>();
static {
servletMappingList.add(new ServletMapping("ExecuteServlet", "/executeServlet", "cn.ybzy.tomcat.servlet.ExecuteServlet"));
}
}
Tomcat入口
public class Tomcat {
private int prot = 8080;
private Map<String, String> urlServletMap = new HashMap<String, String>();
public Tomcat(int prot) {
this.prot = prot;
}
public void start() {
//初始化Url与对应Servlet的关系
this.initServletMapping();
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(prot);
System.out.println("Tomcat starting ....");
while (true) {
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
Request request = new Request(inputStream);
Response response = new Response(outputStream);
//浏览器默认会请求favicon.ico图标
if (!request.getUrl().equals("/favicon.ico")) {
dispatch(request, response);
socket.close();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void initServletMapping() {
List<ServletMapping> servletMappingList = ServletMappingConfig.servletMappingList;
for (ServletMapping servletMapping : servletMappingList) {
urlServletMap.put(servletMapping.getUrl(), servletMapping.getClazz());
}
}
private void dispatch(Request request, Response response) {
String clazz = urlServletMap.get(request.getUrl());
//反射加载对应类
try {
Class<Servlet> servlet = (Class<Servlet>) Class.forName(clazz);
Servlet newInstance = servlet.newInstance();
newInstance.service(request, response);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Tomcat(8888).start();
}
}
整体包结构
执行测试
连接到目标VM, 地址: ''127.0.0.1:12371',传输: '套接字'', 传输: '{1}'
Tomcat starting ....
Request{url='/executeServlet', method='GET'}
Request{url='/favicon.ico', method='GET'}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137063.html