1. Tomcat function
Our web application will run in Tomcat. Obviously, the request must arrive at Tomcat first. Tomcat will actually process the request as follows:
- Provide Socket service: the start of Tomcat must be Socket service, which supports http protocol.
- Request distribution: a Tomcat can provide services for multiple web applications, so the url needs to be distributed to different web applications.
- We need to encapsulate the request and response into request and response: when we write back-end code, we use request and response directly, because Tomcat has done well.
Let's realize these three steps by ourselves.
2. Implementation code
Project structure:
src └─mytomcat BookServlet.java CarServlet.java MyRequest.java MyResponse.java MyServlet.java MyTomcat.java ServletMapping.java ServletMappingConfig.java
2.1 encapsulating http requests and responses
package mytomcat; import java.io.IOException; import java.io.InputStream; /** * Encapsulate http requests */ 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("\n")[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; /** * Encapsulate http response */ 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\n") .append("\r\n") .append(content); outputStream.write(httpResponse.toString().getBytes()); outputStream.close(); } }
2.2 implementing different servlets
package mytomcat; /** * Servlet abstract class */ 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; /** * Process http request for operation 'book' */ 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; /** * Process http request for operation 'vehicle' */ 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 define Servlet mapping POJO class
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 configure Servlet mapping relationship
package mytomcat; import java.util.ArrayList; import java.util.List; /** * Configure the correspondence between the request url and the servlet to be processed */ public class ServletMappingConfig { public static List<ServletMapping> servletMappingList = new ArrayList<>();; static { servletMappingList.add(new ServletMapping("Book", "/book", "mytomcat.BookServlet")); servletMappingList.add(new ServletMapping("Car", "/car", "mytomcat.CarServlet")); } }
2.5 main class
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; //The correspondence between saving request url and processing request servlet private Map<String, String> urlServletMap = new HashMap<String, String>(); 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...\n Listening port:" + port); while(true) { System.out.println("Waiting for a request..."); Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); MyRequest myRequest = new MyRequest(inputStream); MyResponse myResponse = new MyResponse(outputStream); //Request distribution disPatch(myRequest, myResponse); socket.close(); } }catch(IOException e) { e.printStackTrace(); }finally { if(serverSocket != null) { try { serverSocket.close(); }catch(IOException e) { e.printStackTrace(); } } } } //The corresponding relationship between the initialization url and the servlet to be processed private void initServletMapping() { for(ServletMapping servletMapping: ServletMappingConfig.servletMappingList) { urlServletMap.put(servletMapping.getUrl(), servletMapping.getClassName()); } } //Distribute processing requests private void disPatch(MyRequest myRequest, MyResponse myResponse) { String className = urlServletMap.get(myRequest.getUrl()); //reflex try { Class<MyServlet> myServletClass = (Class<MyServlet>) 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(); } }
3. test
Run the MyTomcat main class, and then enter http://localhost:8080/car in the browser. You can see that [get] car... Is returned, and it is finished.
Source address: