Basic implementation of Servlet

Keywords: servlet

preface

Understand the implementation of Servlet and some source code analysis, and understand the source code and function of ServletConfig and ServletContext.

1, Servlet

1. What is a Servlet

1) A set of specifications defined by Java EE, a specification that processes and responds to requests sent by processing clients, that is, interfaces.
2) Servlet, Filter and Listener are three Web components used to process Web client requests.
3) Servlet program is a Java program running in the Web container.

2. A Servlet program

1) Write a class to process the corresponding request, implement the Servlet interface, and rewrite the Service method. The content is the logic to process the request and respond to the request.
2) Configure web.xml to let the container know which servlet class the corresponding request is mapped to handle.

A. Implement servlet

package com.xhu.lls;

import javax.servlet.*;
import java.io.IOException;

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello Servlet!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

B. Configuration mapping

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--Configure the mapping of requests and request processing -->
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.xhu.lls.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

3. Life cycle of Servlet

1) The constructor constructs the servlet object.
2) Initialize according to the configuration file.
Note: a servlet is a singleton multithreading, that is, steps 1 and 2 are executed only when the servlet is accessed for the first time.
3) Execute the service method.
Note: this method is executed once for each request thread, so the service will be executed many times in the life cycle.
4) Destroy servlet object
Note: this method is executed only once when the web container is stopped.

package com.xhu.lls;

import javax.servlet.*;
import java.io.IOException;

public class HelloServlet implements Servlet {
    public HelloServlet(){
        System.out.println("1. structure Servlet object");
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2. Read profile initialization Servlet");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("3. implement service method hello Servlet!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("4. Destroy Servlet object");
    }
}

4. Request distribution

Simultaneous interpreting can be divided into Get and Post requests according to different transmission modes of requests. Two requests have their own characteristics, so there are different ways of handling two requests.

@Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //The servletRequest request accepts an HTTP request, that is, its sub interface HTTPServletRequest, which defines the specification of request type acquisition
        HttpServletRequest hsr = (HttpServletRequest) servletRequest;
        //Get request type
        String rType = hsr.getMethod();
        //Shunting according to type
        if("get".equalsIgnoreCase(rType)) doGet();
        else doPost();
        System.out.println("3. implement service method hello Servlet!");
    }

    private void doGet() {
    }

    private void doPost() {

    }

5. Implement HTTPServlet interface (Servlet sub interface)

A.HelloHTTPServlet

package com.xhu.lls;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * In the actual development, the extended subclass of Servlet is inherited to write Servlet programs
 */
public class HelloHTTPServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

B. Set web.xml

<!--Configure the mapping of requests and request processing -->
    <servlet>
        <servlet-name>helloHttpServlet</servlet-name>
        <servlet-class>com.xhu.lls.HelloHTTPServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloHttpServlet</servlet-name>
        <url-pattern>/newHello</url-pattern>
    </servlet-mapping>

Note: the actual development is new, a servlet class

6. Servlet inheritance tree


Note: Servlet is only responsible for defining the Servlet program access specification; HttpServlet implements distribution, but doPost and doGet only send an msg = "this method is implemented if it is not supported", that is, it is responsible for throwing exceptions; Our custom Servlet needs to override the service method.

A.GenericServlet source code

Only one Service is an abstract class that is not implemented.

public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

B.HttpServlet source code

The distribution logic is basically the same as that written above.

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)res;
        } catch (ClassCastException var6) {
            throw new ServletException("non-HTTP request or response");
        }

        this.service(request, response);
    }
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

2, ServletConfig class

Encapsulate configuration information into classes.

1. Three functions

1) You can get the alias servlet name of the servlet class.
2) Gets the initialization parameter init param.
3) Get servletContext context information (context of lifecycle class)

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    private static final long serialVersionUID = 1L;
    private transient ServletConfig config;
public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}

2. When do I get the config object?

When accessing the Servlet for the first time, Tocmcat will create a Servlet object to handle logic. At this time, the ServletConfig object is also created by Tomcat. Both of them are created by Tomcat and only once in the life cycle, that is, at the beginning.

3,Code and Result

<!--Configure the mapping of requests and request processing -->
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.xhu.lls.HelloServlet</servlet-class>
        <!--Configure initialization parameters-->
        <init-param>
            <param-name>user</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>lls</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/test</param-value>
        </init-param>
        <init-param>
            <param-name>driver</param-name>
            <param-value>com.mysql.jdbc.Driver</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
@Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2. Read profile initialization Servlet");
        //Get servlet name
        String servletName = servletConfig.getServletName();
        System.out.println(servletName);
        //Get parameters
        String user = servletConfig.getInitParameter("user");
        System.out.println(user);
        //Get context
        ServletContext servletContext = servletConfig.getServletContext();
        System.out.println(servletContext);
    }
/**
 * In the actual development, the extended subclass of Servlet is inherited to write Servlet programs
 */
public class HelloHTTPServlet extends HttpServlet {
    //You need to override init with config here, otherwise the parent class will lose config
    @Override
    public void init(ServletConfig config) throws ServletException {
        //Cannot be omitted. The parent class saves config
        super.init(config);
    }

3, ServletContext

1. What is ServletContext?

1) It represents a context interface for all servlet programs of all modules of the project. It is a concept of a domain. It represents how wide the scope is. In this domain, data can be accessed like a Map.
2) Access delete data

setAttribute();getAttribute();removeAttribute();

2. Four functions

1) Get the context parameter context param in web.xml
2) Get the current project path
3) Get the determined path on disk after project deployment
4) Access and delete data like Map

3,Code and Result

<!--Context parameters: parameters shared by the whole project-->
    <context-param>
        <param-name>bossName</param-name>
        <param-value>lls</param-value>
    </context-param>
package com.xhu.lls;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * In the actual development, the extended subclass of Servlet is inherited to write Servlet programs
 */
public class HelloHTTPServlet extends HttpServlet {
    //You need to override init with config here, otherwise the parent class will lose config
    @Override
    public void init(ServletConfig config) throws ServletException {
        //Cannot be omitted. The parent class saves config
        super.init(config);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);
        //Get context param
        ServletContext servletContext = getServletContext();
        System.out.println(servletContext.getInitParameter("bossName"));
        //Get current project path
        System.out.println(servletContext.getContextPath());
        //Get absolute path
        // The context object gets the absolute path based on the current path
        //"/" indicates the current path, that is, the module name we set: / module name,
        //The way to deploy a web project is: Idea integrates Tomcat and uses Catalina_ BASE:   "C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Tomcat_9_0_13_algorithm\conf\Catalina\localhost\book.xml"
        //Its content is a mapping, which means to find the actual location of the resource when requesting access to the project resource
        //<Context path="/moudleName" docBase="realPath" />
        System.out.println(servletContext.getRealPath("/"));
        //Set parameters and get parameters
        servletContext.setAttribute("onlineCount", 10001);
        System.out.println(servletContext.getAttribute("onlineCount"));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

summary

1) Servlet and its implementation
2) ServletConfig, ServletContext interface

reference

[1] tomcat 9
[2] Java web is still in Silicon Valley

Posted by bluebutterflyofyourmind on Tue, 30 Nov 2021 03:11:40 -0800