Overview of ServletContext Interface (Application Domain) and Its Common Methods

ServletContext配置上下文信息

The ServletContext interface is implemented by the org.apache.catalina.core.ApplicationContextFacade provided by the Tomcat server

  • The package name and class name may be different when different servers output ServletContext objects, but they all implement the ServletContext specification

ServletContext is translated as the context object (application domain) of the Servlet object is a member of the Servlet specification, the full class name is jakarta.servlet.ServletContext

  • Tomcat is a container that can hold multiple webapps. For a webapp, there is only one ServletContext object. A ServletContext object usually corresponds to a web.xml file
  • As long as they are in the same webapp, all Servlet objects get the same ServletContext object, that is, share the data in the same application domain
  • If your configuration information wants to work for all Servlets in the current web.xml file, you need to configure it in the context-param tag, and use the ServletContext object to obtain these configuration information

ServletContext object creation and destruction timing (life cycle)

  • The ServletContext object is created when the WEB server is started and destroyed when the web server is closed

获取ServletContext对象

The first way: first obtain the ServletConfig object, and then call the getServletContext method of the Config object to obtain the ServletContext object

public class ContextTestServlet1 extends GenericServlet {
    
    
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    
    
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        // 获取ServletConfig对象
        ServletConfig config = this.getServletConfig();

        // JSP的内置对象的变量名就叫application
        ServletContext application = config.getServletContext();

        // org.apache.catalina.core.ApplicationContextFacade@19187bbb
        out.print("<br>" + application); 
    }
}

The second: directly use this to call the getServletContext method provided by the parent class GenericServlet. The bottom layer is to let the parent class help us call the getServletContext method of the ServletConfig object

public class ContextTestServlet2 extends GenericServlet {
    
    
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    
    
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        // 这里调用父类GenericServlet提供的getServletContext方法
        ServletContext application2 = this.getServletContext();
        
        // org.apache.catalina.core.ApplicationContextFacade@19187bbb
        out.print("<br>" + application2); 
    }
}

As long as they are in the same webapp, all Servlet objects get the same ServletContext object through the getServletContext method, that is, they share the data of the same ServletContext object

  • The ServletContext object corresponding to the ContextTestServlet1 object is org.apache.catalina.core.ApplicationContextFacade@19187bbb
  • The ServletContext object corresponding to the ContextTestServlet2 object is org.apache.catalina.core.ApplicationContextFacade@19187bbb

获取信息记录日志方法

Obtaining application-level configuration information is the method of sharing configuration information and logging in a project (log information is recorded in the logs directory of these Tomcat server copies created by IDEA)

  • IDEA refers to the resources in the Tomcat server installation directory and creates multiple Tomcat server copies, which are stored in the relevant directory of idea (CATALINA_BASE)
# 服务器端的java程序运行的控制台信息
catalina.2021-11-05.log 
# ServletContext对象的log方法记录的日志信息存储到这个文件中 
localhost.2021-11-05.log ServletContext
# 访问日志
localhost_access_log.2021-11-05.txt 
method name Function
String getInitParameter(String name) Get the value through the name in the context-param tag
Enumeration< String > getInitParameterNames() Get the name in all context-param tags
String getContextPath() Dynamically obtain the root path of the application, i.e. /project name, do not write the root path of the application to death in actual development, because you will never know what the name of the application should be when it is finally deployed
String getRealPath(String path) The absolute path to obtain the file is the real path in the server, and the path obtained without parameters is the path where the web project is deployed to the server
void log(String message) Record information to the log, which will not be displayed on the console. If the idea tool is not used, the log will be automatically recorded in the CATALINA_HOME/logs directory
void log(String message, Throwable t) Record the exception object to the log, and the exception will not occur on the console
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0"> 
<!--以下的配置信息属于应用级的配置信息(一个项目中共享的配置信息),可以通过ServletContext对象的方法获取这些信息-->
<!--配置上下文的初始化信息,对当前web.xml文件中的所有的Servlet都起作用-->
<context-param>
    <param-name>pageSize</param-name>
    <param-value>10</param-value>
</context-param>
<context-param>
    <param-name>startIndex</param-name>
    <param-value>0</param-value>
</context-param>
    <servlet>
        <servlet-name>configTest</servlet-name>
        <servlet-class>com.bjpowernode.javaweb.servlet.ConfigTestServlet</servlet-class>
        <!--配置一个Servlet对象的初始化信息的,只对当前的Servet起作用-->
        <init-param>
            <param-name>driver</param-name>
            <param-value>com.mysql.cj.jdbc.Driver</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/bjpowernode</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>configTest</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>

Test the method of the ServletContext object to obtain configuration information and record logs

public class AServlet extends GenericServlet {
    
    
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    
    
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        // 通过this获取ServletContext对象
        ServletContext application = this.getServletContext();
        out.print("ServletContext对象是:" + application + "<br>");

        // 调用ServletContext对象的方法获取上下文的初始化参数
        Enumeration<String> initParameterNames = application.getInitParameterNames();
        while(initParameterNames.hasMoreElements()){
    
    
            String name = initParameterNames.nextElement();
            String value = application.getInitParameter(name);
            out.print(name + "=" + value + "<br>");
        }

        // 获取应用上下文的根即/项目名
        String contextPath = application.getContextPath();
        out.print(contextPath + "<br>");

        // 获取某个文件的绝对路径,默认从从web的根下开始找该文件,“/”代表的是web的根不加也可以
        String realPath = application.getRealPath("/index.html"); 
        String realPath2 = application.getRealPath("index.html"); 
        out.print(realPath + "<br>");

        // 记录信息到日志文件当中
        application.log("今天天气真好!");
		
        // 当年龄小于18岁的时候表示非法,程序出现异常并记录到日志文件当中,控制台上不显示
        int age = 17; 
        if(age < 18) {
    
    
            application.log("对不起,您未成年,请绕行!", new RuntimeException("小屁孩,快走开,不适合你!"));
        }
    }
}

应用域中存储数据方法

The ServletContext object is also called an application domain (similar to a cache). The data in the cache can be fetched directly the next time it is used, and it does not need to be fetched again from the database (hard disk), which reduces IO operations and improves execution efficiency.

The characteristics of data in the application domain: all users share, the amount of data occupies less memory, and the data is rarely modified (generally read-only)

  • There is only one ServletContext object, and it only makes sense to put shared data in it
  • The ServletContext object has a long life cycle and will be destroyed when the server is shut down. Large amounts of data will occupy too much heap memory and affect the performance of the server.
  • If the data shared by all users involves modification operations, there will inevitably be security issues caused by thread concurrency
method name Function
void setAttribute(String name, Object value) Store data in the ServletContext application domain in the form of Object, similar to map.put(k, v)
Object getAttribute(String name) Fetch data from ServletContext application domain, return Object type by default, similar to map.get(k)
void removeAttribute(String name) Delete the data in the ServletContext application domain, similar to map.remove(k)

Entity class User

public class User {
    
    
    private String name;
    private String password;
    public User() {
    
    
    }
    public User(String name, String password) {
    
    
        this.name = name;
        this.password = password;
    }
    //属性的setter和getter方法以及toString方法
}

As long as they are in the same webapp, all Servlet objects get the same ServletContext object, that is, share the data in the same application domain

  • The data stored in the application domain in AServlet can be retrieved from the application domain in BServlet
// 在AServlet中向应用域当中存储数据
public class AServlet extends GenericServlet {
    
    
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    
    
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        // 获取ServletContext对象
        ServletContext application = this.getServletContext();
        out.print("ServletContext对象是:" + application + "<br>");
        // 准备数据
        User user = new User("jack", "123");
        // 向应用域当中存储数据
        application.setAttribute("userObj", user);
    }
}

// 在BServlet中从应用域中取出AServelt存储的数据
public class BServlet extends GenericServlet {
    
    
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    
    
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        
        // AServelt和BServllet获取的是同一个ServletContext对象
        ServletContext application = this.getServletContext();
        out.print("ServletContext对象是:" + application + "<br>");

        // 从应用域中取出AServelt存储的数据
        Object userObj = application.getAttribute("userObj");
        
        // 将对象输出到浏览器
        out.print(userObj + "<br>");
    }
}

Guess you like

Origin blog.csdn.net/qq_57005976/article/details/131129521