In this chapter, we will implement a simple version of Tomcat ourselves. If you have any questions, please contact me at [email protected]. Ask for directions of various gods, thank you
The operation of the program is not without the support of the server, and Tomcat because of its stable performance, free and other advantages, deeply loved by Java enthusiasts and has been recognized by some software developers, for the current more popular Web application server.
So how does it work? Today let’s implement a simplified version of Tomcat to get a feel for it.
Import the JAR package that parses XML
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>Copy the code
Two: write XML parsing classes
package com.example.demo.utils; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * @author zy */ public class XmlUtils {/** * public class XmlUtils */ public Document document; Public XmlUtils(String path) {// Get parser saxReader = new saxReader (); Document = saxreader.read (path); } catch (DocumentException e) { e.printStackTrace(); }} /** * get all nodes under the node ** @param name * @return
*/
public List<Element> getNodes(String name) {
Element root = document.getRootElement();
returnroot.elements(name); }}Copy the code
Three: Implement Request and Response
Request is the encapsulation of the browser’s Request, and Response is the Response to the browser’s Request. In other words, Request is used to retrieve the Request information, and Response is used to add the information to be returned to the browser.
Create Request. Java
package com.example.demo.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* @author zy
*/
public class Request {
private String method;
private String url;
public Request(InputStream inputStream) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String[] methodAndUrl = bufferedReader.readLine().split("");
this.method = methodAndUrl[0];
this.url = methodAndUrl[1];
System.out.println("Request Type:"+ method);
System.out.println("Request path:"+ url);
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getUrl() {
return url;
}
public void setUrl(String url) { this.url = url; }}Copy the code
Create the Response. Java
package com.example.demo.http;
import java.io.OutputStream;
/**
* @author zy
*/
public class Response {
private OutputStream outputStream;
private String write;
public Response(OutputStream outputStream){
this.outputStream = outputStream;
}
public String getWrite() {
return write;
}
public void setWrite(String write) { this.write = write; }}Copy the code
Four: Servlet implementation
Let’s make an interface
package com.example.demo.servlet;
import com.example.demo.http.Request;
import com.example.demo.http.Response;
/**
* @author zy
*/
public abstract class AbstractServlet {
public abstract void doGet(Request request, Response response);
public abstract void doPost(Request request, Response response);
}Copy the code
Then implement your own Servlet
package com.example.demo.servlet;
import com.example.demo.http.Request;
import com.example.demo.http.Response;
/**
* @author zy
*/
public class FirstServlet extends AbstractServlet {
@Override
public void doGet(Request request, Response response) {
response.setWrite("My first Servlet.");
}
@Override
public void doPost(Request request, Response response) { this.doGet(request, response); }}Copy the code
Five: Create web.xml
The mapping of servlets requesting paths is configured here, and the files are placed under the Resources folder
<? xml version="1.0" encoding="UTF-8"? > <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>first.html</servlet-name> <servlet-class>com.example.demo.servlet.FirstServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>first.html</servlet-name> <url-pattern>/first.html</url-pattern> </servlet-mapping> </web-app>Copy the code
6. Create Tomcat and initialize the configuration file
package com.example.demo.tomcat; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.List; import com.example.demo.utils.XmlUtils; import org.dom4j.Element; /** * @author zy */ public class Tomcat {/** * private static final int PORT = 8080; public static final HashMap<String, Object> SERVLET_MAPPING = new HashMap<>(); public static final HashMap<String, Object> SERVLET = new HashMap<>(); /** * Public Boolean tomcatStarBool =true;
private void init() {
InputStream io = null;
try {
System.out.println("Loading configuration file begins"); / / read XmlUtils XML configuration file = new XmlUtils (XmlUtils. Class. GetResource ("/") +"web.xml"); List<Element> List = xml.getNodes("servlet");
for (Element element : list) {
SERVLET.put(element.element("servlet-name").getText(),
Class.forName(element.element("servlet-class").getText()).newInstance()); } // List<Element> list2 = xml.getNodes("servlet-mapping");
for (Element element : list2) {
SERVLET_MAPPING.put(element.element("url-pattern").getText(),
element.element("servlet-name").getText());
}
System.out.println("Loading configuration file completed");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if(io ! = null) { try { io.close(); } catch (Exception e) { e.printStackTrace(); } } } } }Copy the code
Create a SocketProcess to process the requested task
package com.example.demo.tomcat;
import com.example.demo.http.Request;
import com.example.demo.http.Response;
import com.example.demo.servlet.AbstractServlet;
import java.io.OutputStream;
import java.net.Socket;
/**
* @author zy
*/
public class SocketProcess extends Thread{
protected Socket socket;
public SocketProcess(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
Request request = new Request(socket.getInputStream());
Response response = new Response(socket.getOutputStream());
String servletName = (String) Tomcat.SERVLET_MAPPING.get(request.getUrl());
if(servletName! =null && ! Servletname.isempty ()) {AbstractServlet servlet = (AbstractServlet) tomcat.servlet.get (servletName);if(servlet! =null) { servlet.doGet(request, response); }else {
System.out.println("Can't find corresponding servlet"); }}else {
System.out.println("Unable to find servletMapping");
}
String res = response.getWrite();
OutputStream outputStream = socket.getOutputStream();
outputStream.write(res.getBytes("GBK"));
outputStream.flush();
outputStream.close();
}catch (Exception ex){
ex.printStackTrace();
}finally {
if(socket ! = null) { try { socket.close(); } catch (Exception e) { e.printStackTrace(); } } } } }Copy the code
Add startup methods in tomcat. Java
private void start() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Tomcat service started, address: localhost, port:+ PORT); this.init(); // Keep listeningdo{ Socket socket = serverSocket.accept(); Thread Thread = new SocketProcess(socket); thread.start(); }while (tomcatStarBool);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Tomcat tomcat = new Tomcat();
tomcat.start();
}Copy the code
9: test
Start running the void main method in tomcat. Java
If the following information is displayed, the startup is successful. Then enter the following information in the address box
http://localhost:8080/first.html
????? Why is this so…
Ah! No response header information was originally added
The Response. In Java to join
Public static final String RESPONSE_HEADER = public static final String RESPONSE_HEADER ="HTTP / 1.1 200 \ r \ n"
+ "Content-Type: text/html\r\n"
+ "\r\n";Copy the code
SocketProcess. In Java
String res = response.getWrite();Copy the code
to
String res = Response.RESPONSE_HEADER + response.getWrite();Copy the code
Restart, access
At the end
Happy New Year to you all. Thanks for your support!
Other articles:
Build your own Springboot background framework from scratch
Code cloud address: gitee.com/beany/mySpr…
GitHub address: github.com/MyBeany/myS…