Since our Web application is running in tomcat, the request must arrive at Tomcat first. Tomcat actually handles the request as follows.
- First, provide Socket service
The start of Tomcat must be Socket service, but it only supports HTTP protocol!
In fact, we can expand our thinking here. Since Tomcat is based on Socket, what about BIO or NIO or AIO?
- Second, request distribution
To know that a Tomcat can provide services for multiple Web applications, it is obvious that Tomcat can distribute URL s to different Web applications.
- Third, you need to encapsulate the request and response as request/response
We have never encapsulated request/response in the Web application layer. We all use it directly. That's because Tomcat has done a good job for you!
Screenshot of project directory
code
MyReques
MyRequest: used to process requests, obtain request paths and request methods
public class MyRequest { private String url; private String method; public MyRequest(InputStream inputStream) throws IOException { byte[] bytes = new byte[1024]; int length = 0; String httpRequest = ""; if ((length = inputStream.read(bytes)) != 0){ httpRequest = new String (bytes,0,length); } String httpHeader = httpRequest.split("\n")[0]; method = httpHeader.split("\\s")[0]; url = httpHeader.split("\\s")[1]; System.out.println("[my request] method-->" + method + "\turl -->" + url); } getter/setter ...... }
MyResponse
MyResponse: corresponding the result to the browser
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\n") .append("Content-Type: text/html; charset=UTF-8\n") .append("\r\n") .append("<html><body>") .append(content) .append("</body></html>"); outputStream.write(httpResponse.toString().getBytes()); outputStream.close(); } }
MyServlet
MyServlet: abstract class, real response request class, implementation of business logic,
public abstract class MyServlet { public abstract void doGet(MyRequest request,MyResponse response); public abstract void doPst(MyRequest request,MyResponse response); public void service(MyRequest request,MyResponse response){ if ("get".equalsIgnoreCase(request.getMethod())){ doGet(request,response); }else if ("post".equalsIgnoreCase(request.getMethod())){ doPst(request,response); } } }
public class HelloServlet extends MyServlet { public void doGet(MyRequest request, MyResponse response) { try { response.write("HelloServlet Processing get request..."); } catch (IOException e) { e.printStackTrace(); } } public void doPst(MyRequest request, MyResponse response) { try { response.write("HelloServlet Processing post request..."); } catch (IOException e) { e.printStackTrace(); } } }
public class HiServlet extends MyServlet { public void doGet(MyRequest request, MyResponse response) { try { response.write("HiServlet Processing get request..."); } catch (IOException e) { e.printStackTrace(); } } public void doPst(MyRequest request, MyResponse response) { try { response.write("HiServlet Processing post request..."); } catch (IOException e) { e.printStackTrace(); } } }
Servlet configuration
public class ServletMapping { private String url; private String servletName; private String clazz; public ServletMapping(String url, String servletName, String clazz) { this.url = url; this.servletName = servletName; this.clazz = clazz; } getter/setter....... }
public class ServletMappingConfig { public static List<ServletMapping> servletMappingList = new ArrayList<ServletMapping>(); static { servletMappingList.add(new ServletMapping("/hello","HelloServlet","com.cjervin.mytomcat.HelloServlet")); servletMappingList.add(new ServletMapping("/hi","HiServlet","com.cjervin.mytomcat.HiServlet")); } }
Main startup class
public class MyCat { private int port = 8080; private Map<String,Object> servletMap = new HashMap<String, Object>(16); public MyCat(int port){ this.port = port; } //Startup class public static void main(String[] args) { new MyCat(8080).start(); } public void start(){ //Initialize servlet configuration initServletMapping(); ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); System.out.println("[ my tomcat started ...]"); while (true){ Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); MyRequest myRequest = new MyRequest(inputStream); MyResponse myResponse = new MyResponse(outputStream); //Distribution request dispatch(myRequest,myResponse); socket.close(); } } catch (IOException e) { e.printStackTrace(); } finally { if (serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
private void dispatch(MyRequest request, MyResponse response) { String className = (String)servletMap.get(request.getUrl()); if (className == null){ return; } try { Class<MyServlet> clazz = (Class<MyServlet>)Class.forName(className); MyServlet myServlet = clazz.newInstance(); myServlet.service(request, response); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } private void initServletMapping() { for (ServletMapping servletMapping :ServletMappingConfig.servletMappingList) { servletMap.put(servletMapping.getUrl(),servletMapping.getClazz()); } } }
test
Start project test
As you can see, the simple tomcat can be completed here according to different requests. You think it's time to try it.
Source address: https://gitee.com/changxiaojie/myproject.git
reference resources: https://mp.weixin.qq.com/s/zQFml2IFW29uLFXuzBoz8g