摘要:实现一个简单的作用我们的应用会运行在中,那么显然请求必定是先到达的,对于请求实际上会进行如下的处理提供服务的启动,必然是服务,支持协议。进行请求的分发一个可以为多个应用提供服务,那么就需要把下发到不同的应用。下面我们就自己来实现这三步。
实现一个简单的Tomcat 1. Tomcat作用
我们的web应用会运行在Tomcat中,那么显然请求必定是先到达Tomcat的,Tomcat对于请求实际上会进行如下的处理:
提供Socket服务:Tomcat的启动,必然是Socket服务,支持http协议。
进行请求的分发:一个Tomcat可以为多个web应用提供服务,那么就需要把url下发到不同的web应用。
需要将请求和响应封装成request和response:我们在写后端代码的时候都是直接使用request和response的,这是因为Tomcat已经做好了。
下面我们就自己来实现这三步。
2. 实现代码项目结构:
src └─mytomcat BookServlet.java CarServlet.java MyRequest.java MyResponse.java MyServlet.java MyTomcat.java ServletMapping.java ServletMappingConfig.java2.1 封装http请求和响应
package mytomcat; import java.io.IOException; import java.io.InputStream; /** * 封装http请求 */ public class MyRequest { private String url; private String method; public MyRequest(InputStream inputStream) throws IOException { String httpRequest = ""; byte[] httpRequestBytes = new byte[1024]; int length = 0; if((length = inputStream.read(httpRequestBytes)) > 0) { httpRequest = new String(httpRequestBytes, 0, length); } String httpHead = httpRequest.split(" ")[0]; url = httpHead.split("s")[1]; method = httpHead.split("s")[0]; System.out.println(this.toString()); } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } @Override public String toString() { return "MyRequest -- url:" + url + ",method:" + method; } }
package mytomcat; import java.io.IOException; import java.io.OutputStream; /** * 封装http响应 */ public class MyResponse { private OutputStream outputStream; public MyResponse (OutputStream outputStream) { this.outputStream = outputStream; } public void write(String content) throws IOException { StringBuffer httpResponse = new StringBuffer(); httpResponse.append("HTTP/1.1 200 OK ") .append("Content-Type: text/html ") .append(" ") .append(content); outputStream.write(httpResponse.toString().getBytes()); outputStream.close(); } }2.2 实现不同的Servlet
package mytomcat; /** * Servlet抽象类 */ public abstract class MyServlet { public abstract void doGet(MyRequest myRequest, MyResponse myResponse); public abstract void doPost(MyRequest myRequest, MyResponse myResponse); public void service(MyRequest myRequest, MyResponse myResponse) { if(myRequest.getMethod().equalsIgnoreCase("POST")) { doPost(myRequest, myResponse); }else if(myRequest.getMethod().equalsIgnoreCase("GET")) { doGet(myRequest, myResponse); } } }
package mytomcat; import java.io.IOException; /** * 处理操作"书"的http请求 */ public class BookServlet extends MyServlet { @Override public void doGet(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[get] book..."); }catch(IOException e) { e.printStackTrace(); } } @Override public void doPost(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[post] book..."); }catch(IOException e) { e.printStackTrace(); } } }
package mytomcat; import java.io.IOException; /** * 处理操作"车"的http请求 */ public class CarServlet extends MyServlet { @Override public void doGet(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[get] car..."); }catch(IOException e) { e.printStackTrace(); } } @Override public void doPost(MyRequest myRequest, MyResponse myResponse) { try { myResponse.write("[post] car..."); }catch(IOException e) { e.printStackTrace(); } } }2.3 定义Servlet映射POJO类
package mytomcat; public class ServletMapping { private String servletName; private String url; private String className; public ServletMapping(String servletName, String url, String className) { super(); this.servletName = servletName; this.url = url; this.className = className; } public String getServletName() { return servletName; } public void setServletName(String servletName) { this.servletName = servletName; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } }2.4 配置Servlet映射关系
package mytomcat; import java.util.ArrayList; import java.util.List; /** * 配置请求url和处理的servlet的对应关系 */ public class ServletMappingConfig { public static List2.5 主类servletMappingList = new ArrayList<>();; static { servletMappingList.add(new ServletMapping("Book", "/book", "mytomcat.BookServlet")); servletMappingList.add(new ServletMapping("Car", "/car", "mytomcat.CarServlet")); } }
package mytomcat; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; public class MyTomcat { private int port; //保存请求url和处理请求servlet的对应关系 private Map3. 测试urlServletMap = new HashMap (); public MyTomcat(int port) { this.port = port; } public void start() { initServletMapping(); ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); System.out.println("MyTomcat is start... 监听端口:" + port); while(true) { System.out.println("等待请求..."); Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); MyRequest myRequest = new MyRequest(inputStream); MyResponse myResponse = new MyResponse(outputStream); //请求分发 disPatch(myRequest, myResponse); socket.close(); } }catch(IOException e) { e.printStackTrace(); }finally { if(serverSocket != null) { try { serverSocket.close(); }catch(IOException e) { e.printStackTrace(); } } } } //初始化url和处理的servlet的对应关系 private void initServletMapping() { for(ServletMapping servletMapping: ServletMappingConfig.servletMappingList) { urlServletMap.put(servletMapping.getUrl(), servletMapping.getClassName()); } } //分发处理请求 private void disPatch(MyRequest myRequest, MyResponse myResponse) { String className = urlServletMap.get(myRequest.getUrl()); //反射 try { Class myServletClass = (Class ) Class.forName(className); MyServlet myServlet = myServletClass.newInstance(); myServlet.service(myRequest, myResponse); }catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { MyTomcat myTomcat = new MyTomcat(8080); myTomcat.start(); } }
运行MyTomcat主类,然后在浏览器输入http://localhost:8080/car,可以看到返回[get] car...,大功告成。
源码地址:
https://github.com/WangJun-SCU/mytomcat
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/72060.html
摘要:项目结构项目结构如下实现细节创建对象首先创建自定义的请求类,其中定义与两个属性,表示请求的以及请求的方式。其构造函数需要传入一个输入流,该输入流通过客户端的套接字对象得到。创建服务端套接字,并绑定某个端口。 缘起 用了那么久tomcat,突然觉得自己对它或许并没有想象中的那么熟悉,所以趁着放假我研究了一下这只小猫咪,实现了自己的小tomcat,写出这篇文章同大家一起分享! 照例附上gi...
摘要:前言对的管理一直有了解,但是一直没有实际操作一遍,本文从最简单的安装启动开始,通过实例的方式循序渐进的介绍了几种管理的方式。 前言 Nginx+Tomcat对Session的管理一直有了解,但是一直没有实际操作一遍,本文从最简单的安装启动开始,通过实例的方式循序渐进的介绍了几种管理session的方式。 nginx安装配置 1.安装nginx [root@localhost ~]# y...
摘要:创建一个环境最近公司正在使用开发网站应用,所以有必要了解下如何使用创建对应的环境。还好,提供了文档的形式来组合多个容器来搭建开发环境。下一步我们将使用来构建更加复杂的开发环境。 showImg(https://segmentfault.com/img/remote/1460000011106825); 从《从最简单的入手学习 Docker (一)》一文中,可以简单的了解 Docker ...
摘要:在做数据分析和人工智能方面也有很多可以直接使用的算法库。各方面都能找到优秀的组件。但开发起来复杂一些,更适合有一定规模的团队采用。 对语言之间优势这个问题,可以写几本书来具体阐述. 我尝试简单地说一点。不见得对,也不可能完整,仅供参考。 互联网兴起,静态页面不能满足复杂的交互需求. 出现了动态技术.史前时期动态Web 开发多采用CGI 技术来实现. CGI 将脚本作为单独的进程运行, ...
阅读 2618·2021-11-12 10:36
阅读 2256·2021-08-23 09:47
阅读 1674·2019-08-30 15:44
阅读 1399·2019-08-30 14:10
阅读 2240·2019-08-29 16:52
阅读 2333·2019-08-29 16:40
阅读 1581·2019-08-29 16:17
阅读 2406·2019-08-26 13:21