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…