Servlet execution process and file configuration.

Table of contents

 1. Basic introduction

 2. Execution process

 3. Life cycle

 4. Five methods of Servlet

 5. Architecture

 6. urlPattern configuration

 7. XML configuration


1. Basic introduction

▶ Introduction

 Servlet is the core content of JavaWeb. It is a dynamic web resource development technology provided by Java. It can be realized by using Servlet, and different content can be dynamically displayed on the page according to different login users. Servlet is one of the JavaEE specifications, which is actually an interface. In the future, we need to define the Servlet class to implement the Servlet interface, and run the Servlet by the web server. 

▶ Quick Start

 ▷ Requirements Analysis: Write a Servlet class, deploy it using the Tomcat plug-in in IDEA, and finally access the written Servlet program through a browser.

 ▷ The specific implementation steps are:

 1. (According to the previous) create a web project `web-demo`, import Servlet dependent coordinates

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <!--
      此处为什么需要添加该标签?
       provided指的是在编译和测试过程中有效,最后生成的war包时不会加入
      因为Tomcat的lib目录中已经有servlet-api这个jar包,
      如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错
    -->
    <scope>provided</scope>
</dependency>

  2. Create: define a class, implement the Servlet interface, rewrite all methods in the interface, and enter a sentence in the service method

package com.itheima.web;

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

public class ServletDemo1 implements Servlet {

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

 3. Configuration: Use the @WebServlet annotation on the class to configure the access path of the Servlet

@WebServlet("/demo1")

 4. Access: Start Tomcat, enter the URL address in the browser to access the Servlet

http://localhost:8080/web-demo/demo1

 5. After the browser accesses, `servlet hello world~` will be printed on the console, indicating that the servlet program has been successfully run.

2. Execution process

▶ process

 The servlet program is already running normally, but we need to think about a question: We have not created an object of the ServletDemo1 class, nor have we called the service method in the object, why did the sentence `servlet hello world~` be printed on the console?

  1. The browser sends a `http://localhost:8080/web-demo/demo1` request, and three parts can be parsed from the request, namely `localhost:8080`, `web-demo`, `demo1`:
   ○ According to `localhost:8080`, you can find the Tomcat Web server to be accessed.
   ○ According to `web-demo`, you can find the web-demo project deployed on the Tomcat server.
   ○ According to `demo1`, you can find which Servlet in the project you want to access. Class, match according to the value behind @WebServlet
  2. After finding the ServletDemo1 class, the Tomcat Web server will create an object for the ServletDemo1 class, and then call the service method in the object.
  3. ServletDemo1 implements the Servlet interface, so the class must The service method will be rewritten for the Tomcat Web server to call
  4. There are two parameters, ServletRequest and ServletResponse, in the service method. ServletRequest encapsulates the request data, and ServletResponse encapsulates the response data.

▶ Who created the Servlet? Who called the Servlet method?

  Servlets are created by web servers, and servlet methods are called by web servers.

▶ How does the server know that there must be a service method in the Servlet?

  Because our custom Servlet must implement the Servlet interface and override its methods, and there is a service method in the Servlet interface.

3. Life cycle

▶ When did Tomcat create the Servlet object?

 Life cycle: The life cycle of an object refers to the entire process of an object from being created to being destroyed.

▷ Servlet runs in the Servlet container (web server), and its life cycle is managed by the container, which is divided into 4 stages:

  1. Loading and instantiation: By default, when the Servlet is accessed for the first time, the Servlet object is created by the container. By default, a Servlet will be created by the container on the first visit, but if creating a Servlet is time-consuming, the first visitor will have to wait for a long time, and the user experience will be poor, so can we put the Servlet The creation of the server is created when the server is started. How to configure it?

@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
/*
loadOnstartup的取值有两类情况
      (1)负整数:第一次访问时创建Servlet对象
      (2)0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
*/

   2. Initialization: After the Servlet is instantiated, the container will call the Servlet's init() method to initialize the object, and complete some initialization tasks such as loading configuration files and creating connections. This method is called only once.
  3. Request processing: Every time a Servlet is requested, the Servlet container will call the Servlet's service() method to process the request.
  4. Service termination: When the memory needs to be released or the container is closed, the container will call the destroy() method of the Servlet instance to complete the release of resources. After the destroy() method is called, the container releases the Servlet instance, which is then reclaimed by Java's garbage collector.

▶ Cases

package com.itheima.web;
  
  /**
  * Servlet生命周期方法
  */
  @WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
  public class ServletDemo2 implements Servlet {
  
      /**
       *  初始化方法
       *  1.调用时机:默认情况下,Servlet被第一次访问时,调用
       *      loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用
       *  2.调用次数: 1次
       */
      public void init(ServletConfig config) throws ServletException {
          System.out.println("init...");
      }
  
      /**
       * 提供服务
       * 1.调用时机:每一次Servlet被访问时,调用
       * 2.调用次数: 多次
       */
      public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
          System.out.println("servlet hello world~");
      }
  
      /**
       * 销毁方法
       * 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
       * 2.调用次数: 1次
       */
      public void destroy() {
          System.out.println("destroy...");
      }

      public ServletConfig getServletConfig() {
          return null;
      }
  
      public String getServletInfo() {
          return null;
      }
  }

Note: How can the destroy method in the Servlet be executed?

 In the Terminal command line, first use `mvn tomcat7:run` to start, and then use `ctrl+c` to close tomcat

▶ Summary

1. When is the Servlet object created?

  The default is to create when the first visit, you can use the loadOnStartup of @WebServlet(urlPatterns = "/demo2", loadOnStartup = 1) to modify it to create when the server starts.

 2. The three methods involved in the Servlet life cycle, what are these three methods? When are they called? How many times are they called? ○ The init   method
  is executed when the Servlet object is created, only once.
It is called when it is accessed, and it is called once every time it is accessed
  . The destroy method is called when the Servlet object is destroyed, and it is only executed once.

4. Five methods of Servlet

▷ initialization method, executed when the Servlet is created, only executed once

void init(ServletConfig config) 

▷ Provide a service method, which will be called every time the Servlet is accessed

void service(ServletRequest req, ServletResponse res)

▷ Destruction method, when the Servlet is destroyed, this method is called. Destroy Servlet on memory deallocation or server shutdown

void destroy() 

▷ Get Servlet information

String getServletInfo() 
//该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可
public String getServletInfo() {
    return "";
}

▷ Get ServletConfig object

ServletConfig getServletConfig()

▶ attention

 The ServletConfig object is included in the parameters of the init method, and the Tomcat Web server will call the init method when creating the Servlet object, and a ServletConfig object must be passed in. We only need to return the ServletConfig passed by the server.

package com.itheima.web;

@WebServlet(urlPatterns = "/demo3",loadOnStartup = 1)
public class ServletDemo3 implements Servlet {

    private ServletConfig servletConfig;
    
    public void init(ServletConfig config) throws ServletException {
        this.servletConfig = config;
        System.out.println("init...");
    }
    public ServletConfig getServletConfig() {
        return servletConfig;
    }
    
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }

    public void destroy() {
        System.out.println("destroy...");
    }
    
    public String getServletInfo() {
        return "";
    }
}

5. Architecture

▶ Introduction

 If you want to write a Servlet, you must implement the Servlet interface and rewrite the 5 methods in the interface. Although the requirements can be fulfilled, it is still more troublesome to write, because we only pay more attention to the service method. Is there an easier way? How about creating a Servlet? To solve this problem, we need to understand the architecture of the Servlet first:

 Because we will develop web projects with B/S architecture in the future, all of which are aimed at the HTTP protocol, so we customize the Servlet by inheriting HttpServlet

▶ How to write

@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO GET 请求方式处理逻辑
        System.out.println("get...");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO Post 请求方式处理逻辑
        System.out.println("post...");
    }
}

▷ To send a GET request to request the Servlet, you only need to send `http://localhost:8080/web-demo/demo4` through the browser, and you can see that the doGet method is executed. ▷ To send a POST
request , requesting the Servlet cannot be realized through the browser alone. At this time, it is necessary to write a form form to send the request, and create an `a.html` page under the webapp, the content is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/web-demo/demo4" method="post">
        <input name="username"/><input type="submit"/>
    </form>
</body>
</html>

  Start the test and you can see that the doPost method is executed.

▶ Why do HttpServlet call different methods according to different request methods?

 When the front end sends GET and POST requests, the positions of the parameters are inconsistent. The GET request parameters are in the request line, and the POST request parameters are in the request body. In order to handle different request methods, we have to judge in the service method, and then write different business processing:

package com.itheima.web;

@WebServlet("/demo5")
public class ServletDemo5 implements Servlet {

    public void init(ServletConfig config) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        //如何调用?
        //获取请求方式,根据不同的请求方式进行不同的业务处理
        HttpServletRequest request = (HttpServletRequest)req;
       //1. 获取请求方式
        String method = request.getMethod();
        //2. 判断
        if("GET".equals(method)){
            // get方式的处理逻辑
        }else if("POST".equals(method)){
            // post方式的处理逻辑
        }
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

▶ Simplify development

 The above can be achieved, but there will be similar codes in each Servlet class. Is there any optimization strategy for this problem?

1. We can inherit and encapsulate the Servlet interface to simplify code development.

package com.itheima.web;

public class MyHttpServlet implements Servlet {
    public void init(ServletConfig config) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)req;
        //1. 获取请求方式
        String method = request.getMethod();
        //2. 判断
        if("GET".equals(method)){
            // get方式的处理逻辑
            doGet(req,res);
        }else if("POST".equals(method)){
            // post方式的处理逻辑
            doPost(req,res);
        }
    }

    protected void doPost(ServletRequest req, ServletResponse res) {
    }

    protected void doGet(ServletRequest req, ServletResponse res) {
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

2. With the MyHttpServlet class, when we write the Servlet class in the future, we only need to inherit MyHttpServlet and rewrite the doGet and doPost methods in the parent class to process the business logic of GET and POST requests.

@WebServlet("/demo5")
public class ServletDemo5 extends MyHttpServlet {

    @Override
    protected void doGet(ServletRequest req, ServletResponse res) {
        System.out.println("get...");
    }

    @Override
    protected void doPost(ServletRequest req, ServletResponse res) {
        System.out.println("post...");
    }
}

Servlets like MyHttpServlet have been provided for us, that is, HttpServlet, `service()` method, you will find that HttpServlet does more things in the source code, not only can handle GET and POST, but also handle other five request methods .

6. urlPattern configuration

After the Servlet class is written, in order to be accessed, you need to configure its access path (urlPattern)

▶ A Servlet can configure multiple urlPatterns

 package com.itheima.web;
 
  /**
  * urlPattern: 一个Servlet可以配置多个访问路径
  */
  @WebServlet(urlPatterns = {"/demo7","/demo8"})
  public class ServletDemo7 extends MyHttpServlet {
  
      @Override
      protected void doGet(ServletRequest req, ServletResponse res) {
          
          System.out.println("demo7 get...");
      }
      @Override
      protected void doPost(ServletRequest req, ServletResponse res) {
      }
  }

Enter `http://localhost:8080/web-demo/demo7` and `http://localhost:8080/web-demo/demo8` on the browser. These two addresses can access the doGet method of ServletDemo7.

▶ urlPattern configuration rules

 ▷ Exact match

 @WebServlet(urlPatterns = "/user/select")
    public class ServletDemo8 extends MyHttpServlet {
    
        @Override
        protected void doGet(ServletRequest req, ServletResponse res) {
    
            System.out.println("demo8 get...");
        }
        @Override
        protected void doPost(ServletRequest req, ServletResponse res) {
        }
    }

    ● Access path `http://localhost:8080/web-demo/user/select`

▷ Directory matching

     

    @WebServlet(urlPatterns = "/user/*")
    public class ServletDemo9 extends MyHttpServlet {
    
        @Override
        protected void doGet(ServletRequest req, ServletResponse res) {
    
            System.out.println("demo9 get...");
        }
        @Override
        protected void doPost(ServletRequest req, ServletResponse res) {
        }
    }

● Access path `http://localhost:8080/web-demo/user/any`

● Conclusion: `/*` in `/user/*` represents zero or more hierarchical access directories and the priority of exact matching is higher than that of directory matching.

▷ extension match

   

    @WebServlet(urlPatterns = "*.do")
    public class ServletDemo10 extends MyHttpServlet {
    
        @Override
        protected void doGet(ServletRequest req, ServletResponse res) {
    
            System.out.println("demo10 get...");
        }
        @Override
        protected void doPost(ServletRequest req, ServletResponse res) {
        }
    }

● Access path `http://localhost:8080/web-demo/any.do`

● Note:

    1. If the path configuration is not an extension, then `/` must be added in front of the path, otherwise an error will be reported

    2. If the path configuration is `*.do`, then `/` cannot be added in front of *.do, otherwise an error will be reported

▷ Any match

   

    @WebServlet(urlPatterns = "/")
    public class ServletDemo11 extends MyHttpServlet {
    
        @Override
        protected void doGet(ServletRequest req, ServletResponse res) {
    
            System.out.println("demo11 get...");
        }
        @Override
        protected void doPost(ServletRequest req, ServletResponse res) {
        }
    }

● Access path `http://localhost:8080/demo-web/arbitrary`

    @WebServlet(urlPatterns = "/*")
    public class ServletDemo12 extends MyHttpServlet {
    
        @Override
        protected void doGet(ServletRequest req, ServletResponse res) {
    
            System.out.println("demo12 get...");
        }
        @Override
        protected void doPost(ServletRequest req, ServletResponse res) {
        }
    }

● Access path`http://localhost:8080/demo-web/arbitrary

● Note: What is the difference between `/` and `/*`?

    1. When the Servlet in our project is configured with "/", it will overwrite the DefaultServlet in tomcat, and this Servlet will be used when other url-patterns do not match. 2. When our project is configured with "/
    * ", means to match any access path.
    3. DefaultServlet is used to process static resources. If "/" is configured, the default will be overwritten, and it will cause the request for static resources to not use the default but to go custom The Servlet class eventually causes static resources to be inaccessible.

7. XML configuration

  For the previous Servlet configuration, we all use @WebServlet. This is the configuration method that Servlet supports annotation configuration since version 3.0. Before version 3.0, only XML configuration files are supported. There are two steps for XML configuration steps.

▶ The first step: write Servlet class

public class ServletDemo13 extends MyHttpServlet {

    @Override
    protected void doGet(ServletRequest req, ServletResponse res) {

        System.out.println("demo13 get...");
    }
    @Override
    protected void doPost(ServletRequest req, ServletResponse res) {
    }
}

▶ Step 2: Configure the Servlet in web.xml

<?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">

    <!-- 
        Servlet 全类名
    -->
    <servlet>
        <!-- servlet的名称,名字任意-->
        <servlet-name>demo13</servlet-name>
        <!--servlet的类全名-->
        <servlet-class>com.itheima.web.ServletDemo13</servlet-class>
    </servlet>

    <!-- 
        Servlet 访问路径
    -->
    <servlet-mapping>
        <!-- servlet的名称,要和上面的名称一致-->
        <servlet-name>demo13</servlet-name>
        <!-- servlet的访问路径-->
        <url-pattern>/demo13</url-pattern>
    </servlet-mapping>
</web-app>

Compared with annotations, this configuration method is much troublesome to confirm, so it is recommended to use annotations for development.

Guess you like

Origin blog.csdn.net/yzh2776680982/article/details/126807089