Detailed Explanation of JavaWeb Component Servlet

Table of contents

1. Servlet introduction:

2. Servlet interface:

3. The abstract implementation class of Servlet:


1. Servlet introduction:

 1.1 What is a Servlet:

The full name of Servlet is Java Servlet, which is a server-side program written in Java, mainly to dynamically generate web content. A Servlet in a narrow sense refers to an interface implemented by the Java language, and a Servlet in a broad sense refers to any class that implements the Servlet interface. Generally, people understand Servlet as the latter.

    Servlets run on application servers that support Java. In terms of implementation, Servlets can respond to any type of request, but in most cases Servlets are only used to extend Web servers based on the HTTP protocol.

   It acts as an intermediate layer between requests from web browsers or other HTTP clients and databases or applications on HTTP servers.

        The following figure:

1.2. The main tasks of Servlet:

  • Read explicit data sent by the client (browser). This includes HTML forms on web pages, or forms from applets or custom HTTP client programs.
  • Read the implicit HTTP request data sent by the client (browser). This includes cookies, media types, and compression formats that browsers understand, among other things.
  • Process data and generate results. This process may require accessing a database, performing RMI or CORBA calls, invoking a Web service, or computing the corresponding response directly.
  • Send explicit data (ie document) to client (browser). This document can be in a variety of formats, including text files (HTML or XML), binary files (GIF images), Excel, and more.
  • Send an implicit HTTP response to the client (browser). This includes telling the browser or other client what type of document is being returned (such as HTML), setting cookies and caching parameters, and other similar tasks.

2. Servlet interface:

  2.1 Introduction to Servlets:

The Servlet we are talking about is an interface that all Servlet classes must directly or indirectly implement. There are three ways to implement Servlet:

  • Implement the javax.servlet.Servlet interface;

  • Inherit the javax.servlet.GenericServlet class;

  • Inherit the javax.servlet.http.HttpServlet class; (this is what we mainly use)

When we implement Servlet, the Servlet container (server, Tomcat at this stage) will load the Servlet class, and generate a Servlet instance and call specific methods. The Servlet implementation class does not require programmers to create objects themselves, and has already been created in the Servlet container. object.

  important point:

           1. Each Servlet class can only have one instance object (created by the container). 

 2.2 Servlet workflow:

When the client sends a request to the server, the server will create a request object, a response object, and encapsulate the request data into the request. The response object is used to respond to the client, and then passed when calling the Servlet.service() method For the service() method, call the sevice() method to process the data to form dynamic data, and then respond to the client through the response object.          

   The main function of request:

  • Encapsulates the request header data;

  • Encapsulates the request body data, if it is a GET request, then there is no body;

  • request is a domain object, which can be used as a Map to add and obtain data;

  • request provides request forwarding and request inclusion functions.

 

 The main function of response:

  • Set the response header information;

  • send status code;

  • Set the response body;

  • redirect;

2.3 Methods of Servlet interface:

The Servlet interface defines five methods:

 * 实现Servlet的第一种方式
 *   实现javax.servlet.Servlet接口
 
public class AServlet implements Servlet {
    private ServletConfig servletConfig; //默认null

    /**
     * 初始化方法    生命周期方法, 由Tomcat调用    做初始化操作
     *   在Servlet创建之后调用, 调用一次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("555~~555,我出生了...");
        this.servletConfig = servletConfig;
    }

    /**
     * 得到ServletConfig对象 (Servlet的配置)
     *
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }

    /**
     * 最重要的方法, 接收用户请求,处理用户请求, 响应结果
     * Tomcat调用:  生命周期方法   , 每请求一次,执行一次
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("AServlet 正在服务...");
        //获取Servlet配置
        //System.out.println("Servlet的名字:"+servletConfig.getServletName());
        //获取初始化参数
        //根据初始化参数名获取值
        String name = servletConfig.getInitParameter("name");
        System.out.println("name:"+name);
        //获取所有的初始化参数名
        Enumeration<String> names = servletConfig.getInitParameterNames();
        //遍历
        while(names.hasMoreElements()){
            String key = names.nextElement(); //参数名
            String value = servletConfig.getInitParameter(key);
            System.out.println("key:"+key+"--value:"+value);
        }

    }

    /**
     * 没什么意义
     *   得到Servlet的描述
     * @return
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 销毁方法,    释放资源
     *  生命周期方法, Tomcat调用,
     *   在Servlet销毁之前调用, 只执行一次
     */
    @Override
    public void destroy() {
        System.out.println("555~555~我走了...");
    }
}

 These five methods describe the life cycle of a Servlet, from birth to death:

 Born : By default, created by Tomcat when requested for the first time.

            Call the init method.

   Operation : Every time the user requests this Servlet, tomcat calls the service() method once.

   Death : Before the Tomcat server shuts down, destroy all objects it created, including creating Servlets, and call destroy() before the Servlets are destroyed

 

2.4 ServletConfig interface:

When the Servlet container initializes the Servlet, the Servlet container will pass in a ServletConfig object to the init( ) method of the Servlet. ServletConfig object, created by the server.

  Main method:

  • String getServletName(): Get the configuration name of the Servlet in the web.xml file, that is, the name specified by <servlet-name>;

  • ServletContext getServletContext(): used to obtain the ServletContext object,

  • String getInitParameter(String name): Used to obtain the initialization parameters configured in web.xml, and obtain parameter values ​​through the parameter name;

  • Enumeration getInitParameterNames(): used to obtain the names of all initialization parameters configured in web.xml;

 

2.5 ServletContext object:

A ServletContext object represents a Servlet application. Each web application has only one ServletContext object . In a distributed environment where an application is deployed to multiple containers at the same time, each Web application on a Java virtual machine will have a ServletContext object.

 The role of the ServletContext object is to share data between the dynamic resources of the entire Web application ! For example, save a value to the ServletContext object in AServlet, and then get this value in BServlet, which is shared data.

                The ServletContext object can also be obtained by calling the getServletContext method in ServletConfig.

In HttpServlet, you can directly call the getServletConfig() method, because HttpServlet inherits GenericServlet, and GenericServlet implements ServletConfig, and GenericServlet has getServletConfig(), so you can directly call in HttpServlet to get the ServletContext object.

    ServletContext servletContext = getServletConfig().getServletContext();

3. The abstract implementation class of Servlet:

3.1 GenericServlet abstract class:

We have always written Servlets by implementing the Servlet interface. However, using this method, you must implement all the methods defined in the Servlet interface. Manually maintain a reference to the ServletConfig object. Therefore, it is more troublesome to implement Servlet in this way.
   The GenericServlet abstract class has three benefits:

1. Provides default implementations for all methods in the Servlet interface, so programmers can directly change what they need, and no longer need to implement all methods by themselves.

2. And provide methods to surround the methods in the ServletConfig object.

3. The ServletConfig parameter in the init ( ) method is assigned to an internal ServletConfig reference to save the ServletConfig object, and the programmer does not need to maintain the ServletConfig by himself.

Note: But we rarely use the GenericServlet abstract class, because we mainly use HttpServlet

The following is the GenericServlet abstract class code:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.servlet;

import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;

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

    public GenericServlet() {
    }

    public void destroy() {
    }

    public String getInitParameter(String name) {
        return this.getServletConfig().getInitParameter(name);
    }

    public Enumeration<String> getInitParameterNames() {
        return this.getServletConfig().getInitParameterNames();
    }

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
    }

    public String getServletInfo() {
        return "";
    }

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {
    }

    public void log(String message) {
        this.getServletContext().log(this.getServletName() + ": " + message);
    }

    public void log(String message, Throwable t) {
        this.getServletContext().log(this.getServletName() + ": " + message, t);
    }

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

    public String getServletName() {
        return this.config.getServletName();
    }
}

 3.2 HttpServlet abstract class:

The HttpServlet class is a subclass of GenericServlet, which provides special support for HTTP requests, so the HttpServlet abstract class covers the Service ( ) method in the GenericServlet abstract class, and adds a unique Service (HttpServletRequest request, HttpServletResponse method.

 

The service method in HttpServlet converts the received ServletRequsest type object into HttpServletRequest type object, and converts the ServletResponse type object into HttpServletResponse type object. The reason why such a forced conversion is possible is because when calling the Service method of the Servlet, the Servlet container will always pass in an HttpServletRequest object and an HttpServletResponse object, ready to use HTTP. So of course there is nothing wrong with converting types.

    After conversion, the service method passes the two converted objects into another service method, so let's take a look at how this method is implemented:
 

 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);
        }

    }

The parameters of this service method are the HttpServletRequest object and the HttpServletResponse object, which just received the two objects passed by the previous service method. We will find that there is still no service logic in the service method, but it is parsing the method parameters in HttpServletRequest, and calling the following methods doGet, doPost, doHead, doPut, doTrace, doOptions and doDelete. Each of these seven methods represents an Http method. doGet and doPost are the most commonly used. Therefore, if we need to implement specific service logic, we no longer need to override the service method, we only need to override doGet or doPost. So we only need to write the doget and doPost methods. This makes the code more concise.

public class aServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

 

Guess you like

Origin blog.csdn.net/qq_50692350/article/details/127417513