“This is my 38th day of participating in the First Challenge 2022. For details: First Challenge 2022”

Spring integration with JavaWeb enables Spring to control transactions and manage databases, and the Spring container can manage Java beans, helping to reduce code coupling.

Spring integrates the Java Web

1.1 Project Construction

Create the Porsche table in the database

DROP TABLE IF EXISTS `porsche`;
CREATE TABLE `porsche` (
  `por_id` int(11) NOT NULL AUTO_INCREMENT,
  `por_name` char(100) CHARACTER SET gb2312 COLLATE gb2312_chinese_ci DEFAULT NULL,
  `por_price` double DEFAULT NULL,
  `por_stock` int(11) DEFAULT NULL.PRIMARY KEY (`por_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=gb2312;

-- ----------------------------
-- Records of porsche
-- ----------------------------
BEGIN;
INSERT INTO `porsche` VALUES (2.'Cayenne'.910000.30);
INSERT INTO `porsche` VALUES (3.'Macan'.550000.40);
INSERT INTO `porsche` VALUES (4.'Taycay 2022'.880000.50);
INSERT INTO `porsche` VALUES (5.'Porsche 911'.1270000.40);
INSERT INTO `porsche` VALUES (6.'Porsche 718'.540000.70);
INSERT INTO `porsche` VALUES (7.'918 Spyder'.13380000.10);
INSERT INTO `porsche` VALUES (8.'Cayman'.720000.30);
INSERT INTO `porsche` VALUES (9.'Boxster'.670000.110);
INSERT INTO `porsche` VALUES (10.'Carrera GT'.6450000.20);
INSERT INTO `porsche` VALUES (11.'Taycan Tubo S'.880000.140);
INSERT INTO `porsche` VALUES (12.'Taycan 2023'.880000.120);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;
Copy the code

Create a Maven project using IDEA, add Spring IoC container dependencies, database driver dependencies, and other dependencies such as JSP to the POM.xml file.

<properties>
    <spring-version>5.3.13</spring-version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <! -- Spring JDBC dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.14</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <! -- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
    <dependency>
        <groupId>javax.servlet.jsp.jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
Copy the code

To Add Add Framework Support, select Web Application

1.2 Adding Configurations

Add the Spring configuration file application.xml in the Resource directory


      
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <! -- Packet scanning configuration -->
    <context:component-scan base-package="com.citi"/>
    <! -- Reference external configuration file -->
    <context:property-placeholder location="classpath:database.properties"></context:property-placeholder>

    <! Database connection pool configuration -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driverClassName}"/>
        <property name="url" value="${url}" />
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
        <property name="initialSize" value="${initialSize}"/>
        <property name="maxActive" value="${maxActive}"/>
    </bean>

    <! Insert JDBC Template into the Spring container
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    </bean>

    <! -- Transaction manager configuration -->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <! -- Enable annotation-based configuration mode -->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
</beans>
Copy the code

Add database.properties to the database connection information configuration in the resource directory

driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/tx? useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username=root password=root initialSize=5 maxActive=20Copy the code

1.3 test

Added entity package, added entity class Porsche corresponding to porsche table

public class Porsche { private Integer porId; private String porName; private Double porPrice; private Integer porStock; // omit the getter/setter/toString method}Copy the code

New DAO package, PorscheDao, @repository annotation on class, managed by Spring container; And use the Spring JdbcTemplate to manipulate the database

@Repository
public class PorscheDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<Porsche> selectAll(a){

        String selectAllSql = "SELECT por_id, por_name, por_price, por_stock FROM porsche";
        RowMapper rowMapper = new BeanPropertyRowMapper<>(Porsche.class);
        List<Porsche> porscheList = jdbcTemplate.query(selectAllSql, rowMapper);
        returnporscheList; }}Copy the code

Add a test class, PorscheDaoTest, under the Test package to test selectAll methods

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class PorscheDaoTest {

    @Resource
    private PorscheDao porscheDao;

    @Test
    public void selectAll(a) {

        List<Porsche> porscheList = porscheDao.selectAll();
        for(Porsche porsche : porscheList) { System.out.println(porsche); }}}Copy the code

Perform the testOutput all the data in the Porsche table, consistent with the expected target.

Added Service package, added PorsheService

@Service
public class PorscheService {

    @Autowired
    private PorscheDao porscheDao;

    public List<Porsche> getPorscheList(a){
        returnporscheDao.selectAll(); }}Copy the code

Added controller package, added PorscheController. This class calls getPorscheList of PorscheService to obtain all data and display it on the page

public class PorscheController extends HttpServlet {}Copy the code

For Web projects, the PorscheController object is created by the Tomcat container for the first time after a successful startup. Objects created by the IOC container and objects created by Tomcat have no connection. Controller objects are created by Tomact. You cannot add @Controller annotations to classes

PorscheController object want to get PorscheService object can not be obtained by @autowired way, can be obtained by IOC container tool, add util package, implement IOC container tool ContextUtil

public class ContextUtil {

    public static Object getBean(String beanName){
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
        Object bean = context.getBean(beanName);
        returnbean; }}Copy the code

Test the utility class

public class ContextUtilTest {

    @Test
    public void getBean(a) {

        Object porscheService = ContextUtil.getBean("porscheService"); System.out.println(porscheService); }}Copy the code

Perform the test

The PorscheService can be retrieved from the utility class, so you can call getPorscheList to get all the data

public class PorscheController extends HttpServlet {

    private PorscheService porscheService = (PorscheService) ContextUtil.getBean("porscheService");

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // Query all data
        List<Porsche> porscheList = porscheService.getPorscheList();
        request.setAttribute("porscheList",porscheList);
        request.getRequestDispatcher("index.jsp").forward(request,response);
        for (Porsche porsche : porscheList) {
            System.out.println(porsche);
        }
        System.out.println("DoGet called"); }}Copy the code

Get and display the data in index.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Index</title>
  </head>
  <body>
    ${requestScope.porscheList}
  </body>
</html>
Copy the code

Configure the PorscheController access path in web. XML

<servlet>
    <description></description>
    <display-name>PorscheController</display-name>
    <servlet-name>PorscheController</servlet-name>
    <servlet-class>com.citi.controller.PorscheController</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>PorscheController</servlet-name>
    <url-pattern>/porsches</url-pattern>
</servlet-mapping>
Copy the code

Open Project Structure, select Artifacts, and import all the JAR packages on the right into the new lib folder in the WEB-INF directory on the left

Configure Tomcat

Start Tomcat, the browser enter http://localhost:8080/porsches

Spring integration with Java Web is successful

1.4 Functions of listeners

The PorscheService is retrieved from the IoC container tool ContextUtil in ProscheController, and a new IoC container is retrieved from ContextUtil in the following line.

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
Copy the code

But here only the code that creates the container does not destroy the container, resulting in a full memory situation. Therefore, the IoC container is expected to be created and destroyed at the appropriate time, that is, the IoC container is created when the project is started and destroyed when the project is destroyed.

The ContextLoaderListener in Spring Web listens on the Tomcat container and provides methods for creating and destroying IoC containers, Check the org. Springframework. Web. Context. ContextLoaderListener source

This class provides methods for container initialization and destruction

1.4.1 Using Listeners

The first step is to add Spring Web dependencies to pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring-version}</version>
</dependency>
Copy the code

Web.xml adds the configuration of the listener, and you also need to configure the path to the Spring configuration file. The listener uses the configuration in the Spring configuration file to create the Spring container

<! -- Listener dependent configuration -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:application.xml</param-value>
</context-param>
<! -- Listener -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Copy the code

ContextUtil don’t need through new ClassPathXmlApplicationContext (” classpath: application. XML “) way to get the IoC container. Can pass ContextLoader. GetCurrentWebApplicationContext () to obtain; Modify the ContextUtil getBean method code

public static Object getBean(String beanName){
    WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
    Object bean = context.getBean(beanName);
    return bean;
}
Copy the code

Restart the Tomcat, the browser to enter http://localhost:8080/porsches again

Successfully output all data

Spring’s integration with Java Web is officially complete and has been successfully verified!