Understand the details of using spring framework in web Environment (facilitate the integration after understanding)

Summary:

  1. Containers are no longer created every time, that is, spring configuration files or configuration classes no longer need to be loaded multiple times It is designed to create app objects as soon as the web application starts
  2. The configuration name can be ignored, that is, the configuration name is different, and you only need to modify the web XML file without touching the source code
  3. You can hide the key name of the app object (in the domain)

Integration of spring and web Environment

Now POM Import jar package from XML
One is serlvet and the other is jsp

		<dependency>
          <!--Servlet of jar package-->
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
      </dependency>
      <dependency>
          <!--jsp of jar package-->
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.1</version>
      </dependency>

With these two packages, you can write things about the web layer
Note: what is the Mvc design pattern and what is the three-tier architecture of software development

Disadvantages at this time

When writing controller code, for the acquisition method of app object, when there is more business, the spring configuration file (or main configuration class) will be loaded a lot. In fact, this is meaningless. In fact, the loc container only needs to be created once

resolvent

In a web project, you can use ServletContextListener to monitor the start of a web application. When the web application starts, you can load the loc container of spring, that is, the app object, and store it in the largest domain ServletContext, so that you can get the app object at any location

Code example

/*
* This interface is implemented to listen when the web application starts*/
public class ContextLoaderListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("app",app);
        System.out.println("loc The container is created...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}

Here, if you use maven's tomcat plug-in run, an error will be reported. You should configure local tomcat for this project in the idea to start

E:\Tomcat\apache-tomcat-8.5.66\bin\catalina.bat run
[2021-12-20 12:28:39,234] Artifact lea:war exploded: Waiting for server connection to start artifact deployment...
Using CATALINA_BASE:   "C:\Users\LYD\.IntelliJIdea2018.3\system\tomcat\Unnamed_lea"
Using CATALINA_HOME:   "E:\Tomcat\apache-tomcat-8.5.66"
Using CATALINA_TMPDIR: "E:\Tomcat\apache-tomcat-8.5.66\temp"
Using JRE_HOME:        "C:\Java\jdk-13.0.2"
Using CLASSPATH:       "E:\Tomcat\apache-tomcat-8.5.66\bin\bootstrap.jar;E:\Tomcat\apache-tomcat-8.5.66\bin\tomcat-juli.jar"
Using CATALINA_OPTS:   ""
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
20-Dec-2021 12:28:40.472 information [main] org.apache.catalina.startup.VersionLoggerListener.log Server.Server version: Apache Tomcat/8.5.66
20-Dec-2021 12:28:40.473 information [main] org.apache.catalina.startup.VersionLoggerListener.log Server construction:        May 8 2021 22:44:01 UTC
20-Dec-2021 12:28:40.474 information [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number:      8.5.66.0
20-Dec-2021 12:28:40.474 information [main] org.apache.catalina.startup.VersionLoggerListener.log Operating system name:      Windows 10
20-Dec-2021 12:28:40.474 information [main] org.apache.catalina.startup.VersionLoggerListener.log OS.edition:           10.0
20-Dec-2021 12:28:40.475 information [main] org.apache.catalina.startup.VersionLoggerListener.log framework:              amd64
20-Dec-2021 12:28:40.475 information [main] org.apache.catalina.startup.VersionLoggerListener.log Java environment variable:     C:\Java\jdk-13.0.2
20-Dec-2021 12:28:40.475 information [main] org.apache.catalina.startup.VersionLoggerListener.log Java Virtual machine version:    13.0.2+8
20-Dec-2021 12:28:40.475 information [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.supplier:        Oracle Corporation
20-Dec-2021 12:28:40.475 information [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:     C:\Users\LYD\.IntelliJIdea2018.3\system\tomcat\Unnamed_lea
20-Dec-2021 12:28:40.475 information [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:     E:\Tomcat\apache-tomcat-8.5.66
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       --add-opens=java.base/java.lang=ALL-UNNAMED
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       --add-opens=java.base/java.io=ALL-UNNAMED
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       --add-opens=java.base/java.util=ALL-UNNAMED
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Djava.util.logging.config.file=C:\Users\LYD\.IntelliJIdea2018.3\system\tomcat\Unnamed_lea\conf\logging.properties
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dcom.sun.management.jmxremote=
20-Dec-2021 12:28:40.476 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dcom.sun.management.jmxremote.port=1099
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dcom.sun.management.jmxremote.ssl=false
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dcom.sun.management.jmxremote.authenticate=false
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Djava.rmi.server.hostname=127.0.0.1
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Djdk.tls.ephemeralDHKeySize=2048
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dignore.endorsed.dirs=
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dcatalina.base=C:\Users\LYD\.IntelliJIdea2018.3\system\tomcat\Unnamed_lea
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Dcatalina.home=E:\Tomcat\apache-tomcat-8.5.66
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.startup.VersionLoggerListener.log Command line parameters:       -Djava.io.tmpdir=E:\Tomcat\apache-tomcat-8.5.66\temp
20-Dec-2021 12:28:40.477 information [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent use APR edition[1.7.0]Loaded based on APR of Apache Tomcat Local library[1.2.28]. 
20-Dec-2021 12:28:40.478 information [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR Function: IPv6[true],sendfile[true],accept filters[false],random[true]. 
20-Dec-2021 12:28:40.478 information [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL to configure: useAprConnector[false],useOpenSSL[true]
20-Dec-2021 12:28:40.481 information [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL Successfully initialized [OpenSSL 1.1.1k  25 Mar 2021]
20-Dec-2021 12:28:40.529 information [main] org.apache.coyote.AbstractProtocol.init Initialize protocol processor ["http-nio-8080"]
20-Dec-2021 12:28:40.831 information [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
20-Dec-2021 12:28:40.845 information [main] org.apache.catalina.startup.Catalina.load Initialization processed in 822 ms
20-Dec-2021 12:28:40.891 information [main] org.apache.catalina.core.StandardService.startInternal Starting service[Catalina]
20-Dec-2021 12:28:40.892 information [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine:[Apache Tomcat/8.5.66]
20-Dec-2021 12:28:40.903 information [main] org.apache.coyote.AbstractProtocol.start Start protocol processing handle["http-nio-8080"]
20-Dec-2021 12:28:40.915 information [main] org.apache.catalina.startup.Catalina.start Server startup in 68 ms
Connected to server
[2021-12-20 12:28:41,339] Artifact lea:war exploded: Artifact is being deployed, please wait...
20-Dec-2021 12:28:42.364 information [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR Scanned for TLD But not yet included TLD.  Enable debug logging for this logger to get scanned but not found in it TLD Integrity of JAR List. Skip unneeded during scan JAR Can reduce startup time and JSP Compile time.
20-Dec-2021 12:28:42.595 information [RMI TCP Connection(3)-127.0.0.1] org.springframework.context.support.AbstractApplicationContext.prepareRefresh Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@57765b41: startup date [Mon Dec 20 12:28:42 CST 2021]; root of context hierarchy
loc The container is created...
20-Dec-2021 12:28:43.416 warning [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom use[SHA1PRNG]Create session ID Generated SecureRandom Instance cost[290]millisecond.
[2021-12-20 12:28:43,443] Artifact lea:war exploded: Artifact is deployed successfully
[2021-12-20 12:28:43,443] Artifact lea:war exploded: Deploy took 2,105 milliseconds
20-Dec-2021 12:28:50.905 information [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory hold web Application deployment to directory [E:\Tomcat\apache-tomcat-8.5.66\webapps\manager]
20-Dec-2021 12:28:50.946 information [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Web Application directory[E:\Tomcat\apache-tomcat-8.5.66\webapps\manager]Your deployment is already in progress[41]Completed in milliseconds

Use the app object in the ServletContext domain

@WebServlet("/saveUserServlet")
public class SaveUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        ApplicationContext app = (ApplicationContext)servletContext.getAttribute("app");
        UserService userService = (UserService)app.getBean("userService");
        userService.save();
    }

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

Open browser access

http://localhost:8080/lea_war_exploded/saveUserServlet

Console printing

20-Dec-2021 16:36:45.943 warning [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom use[SHA1PRNG]Create session ID Generated SecureRandom Instance cost[294]millisecond.
[2021-12-20 04:36:45,965] Artifact lea:war exploded: Artifact is deployed successfully
[2021-12-20 04:36:45,965] Artifact lea:war exploded: Deploy took 5,504 milliseconds
20-Dec-2021 16:36:47.217 information [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory hold web Application deployment to directory [E:\Tomcat\apache-tomcat-8.5.66\webapps\manager]
20-Dec-2021 16:36:47.257 information [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Web Application directory[E:\Tomcat\apache-tomcat-8.5.66\webapps\manager]Your deployment is already in progress[40]Completed in milliseconds
 This is Orale Implementation method of
 Method of persistence layer called

In case someone's project's spring configuration file is not called ApplicationContext XML or spring's main configuration class is not called SpringConfiguration At this time, the place where the app is obtained in the original code needs to modify the code How can you make the code ignore the spring configuration file name or the main configuration class name?

On the web Configuring global variables in XML
for example

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--Global initialization variable-->
  <context-param>
    <param-name>contextConfiguration</param-name>
    <param-value>SpringConfiguration.class</param-value>
  </context-param>

  <!--Configure listener-->
  <listener>
    <listener-class>web.listener.ContextLoaderListener</listener-class>
  </listener>



</web-app>

Summary: one thing to note here is that the global initialization variable can only be set at the top, otherwise an error will be reported
Then modify the code at the listener:

/*
* This interface is implemented to listen when the web application starts*/
public class ContextLoaderListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        
        ServletContext servletContext = sce.getServletContext();
        //Read parameters
        String contextConfiguration = servletContext.getInitParameter("contextConfiguration");
        //Use the global variable to obtain the app object. Even if the name of the spring configuration is different, only modify the web xml
        ApplicationContext app = new AnnotationConfigApplicationContext(contextConfiguration);
        servletContext.setAttribute("app",app);
        System.out.println("loc The container is created...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}

Consider it further here. If you don't know the key name of the app stored in the ServletContext field, it's called app? How about not having to remember the key name?

Write a tool class

package utils;

import org.springframework.context.ApplicationContext;

import javax.servlet.ServletContext;

public class WebApplicationContextUtils {
    public static ApplicationContext getApp(ServletContext servletContext){
        return (ApplicationContext)servletContext.getAttribute("app");
    }
}

Modify the code where the app object is used

@WebServlet("/saveUserServlet")
public class SaveUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        /*ApplicationContext app = (ApplicationContext)servletContext.getAttribute("app");*/
        //Using this tool class, you can completely ignore the key name of the app in the domain
        ApplicationContext app = WebApplicationContextUtils.getApp(servletContext);
        UserService userService = (UserService)app.getBean("userService");
        userService.save();
    }

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

Keywords: Front-end Spring mvc

Added by Tryfan on Wed, 22 Dec 2021 08:59:20 +0200