Spring MVC integration and cases

Posted by mlnsharma on Wed, 23 Feb 2022 03:50:03 +0100

5.5 the controller responds to the front-end request

5.4.1 response to synchronization request

Response to synchronization request: the front end sends a request to the method in the controller class. After the controller method processes the request, it needs to jump to the next page

  • Front end request

    <a href="book/list?pageNum=1&pageSize=10">Get book information (synchronization)<a>
    
  • The controller responds to the synchronization request: the return type of the controller method processing the synchronization request is String or ModelAndView

    • forward
    @RequestMapping("/list")
    public String list(int pageNum,int pageSize){
        //...
        return "/book-list.jsp";
    }
    
    @RequestMapping("/list")
    public ModelAndView list(int pageNum, int pageSize){
    	//...
        ModelAndView modelAndView = new ModelAndView("/book-list.jsp");
        return modelAndView;
    }
    
    • redirect
    @RequestMapping("/list")
    public String list(int pageNum, int pageSize){
        //...
        return "redirect:/book-list.jsp";
    }
    
    @RequestMapping("/list")
    public ModelAndView list(int pageNum, int pageSize){
    	//...
        ModelAndView modelAndView = new ModelAndView("redirect:/book-list.jsp");
        return modelAndView;
    }
    
5.4.2 responding to asynchronous requests

Respond to asynchronous requests: no page jump occurs, and the data is directly returned to the ajax request

  • Send ajax requests to the front end

    <button id="listBtn">Get book information (asynchronous)</button>
    <script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        $("#listBtn").click(function(){
        $.ajax({
            url:"book/list2",
            type:"get",
            data:{pageNum:1,pageSize:10},
            success:function (res) {
                console.log(res);
            }
        });
    });
    </script>
    
  • The control method responds to ajax requests

    Method 1: use the output stream of the response object to respond to ajax requests

    @RequestMapping("/list2")
    public void list2(int pageNum, int pageSize, HttpServletResponse response) throws IOException {
        List<Book> bookList = new ArrayList<Book>();
        bookList.add(new Book(1,"Java1","Xiao San Zhang",22.22,new Date(),"666"));
        bookList.add(new Book(2,"Java2","Zhang San",22.22,new Date(),"666"));
        bookList.add(new Book(3,"Java3","Da San Zhang",22.22,new Date(),"666"));
    
        String jsonStr = new ObjectMapper().writeValueAsString(bookList);
    
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.write(jsonStr);
        out.flush();
        out.close();
    }
    

    Method 2: change the return type of the control method to the type of data to respond to, and directly return the data to respond in the controller method

    • Need to rely on Jackson databind dependency
    • The @ ResponseBody annotation needs to be added to the controller method
    @ResponseBody
    @RequestMapping("/list2")
    public List<Book> list2(int pageNum, int pageSize) throws IOException {
        List<Book> bookList = new ArrayList<Book>();
        bookList.add(new Book(1,"Java1","Xiao San Zhang",22.22,new Date(),"666"));
        bookList.add(new Book(2,"Java2","Zhang San",22.22,new Date(),"666"));
        bookList.add(new Book(3,"Java3","Da San Zhang",22.22,new Date(),"666"));
        return bookList;
    }
    

5.6 the controller transmits the value to the next page

Controller method for processing synchronization request

Method 1: the return type of the controller method is ModelAndView, and the ModelAndView object is directly used to carry data

@RequestMapping("/list")
public ModelAndView list(int pageNum, int pageSize){
    List<Book> bookList = new ArrayList<Book>();
    bookList.add(new Book(1,"Java1","Xiao San Zhang",22.22,new Date(),"666"));
    bookList.add(new Book(2,"Java2","Zhang San",22.22,new Date(),"666"));
    bookList.add(new Book(3,"Java3","Da San Zhang",22.22,new Date(),"666"));

    ModelAndView modelAndView = new ModelAndView("/book-list.jsp");
    modelAndView.addObject("bookList",bookList);
    return modelAndView;
}

Method 2: the return type of the controller method is String, add the HttpServletRequest parameter in the control method, and use the request object to pass the value

@RequestMapping("/list")
public String list(int pageNum, int pageSize, HttpServletRequest request){
    List<Book> bookList = new ArrayList<Book>();
    bookList.add(new Book(1,"Java1","Xiao San Zhang",22.22,new Date(),"666"));
    bookList.add(new Book(2,"Java2","Zhang San",22.22,new Date(),"666"));
    bookList.add(new Book(3,"Java3","Da San Zhang",22.22,new Date(),"666"));

    request.setAttribute("bookList",bookList);
    return "/book-list.jsp";
}

Method 3: the return type of the controller method is String, add the model parameter to the control method, and use the model object to pass the value

@RequestMapping("/list")
public String list(int pageNum, int pageSize, Model model){
    List<Book> bookList = new ArrayList<Book>();
    bookList.add(new Book(1,"Java1","Xiao San Zhang",22.22,new Date(),"666"));
    bookList.add(new Book(2,"Java2","Zhang San",22.22,new Date(),"666"));
    bookList.add(new Book(3,"Java3","Da San Zhang",22.22,new Date(),"666"));

    model.addAttribute("bookList",bookList);
    return "/book-list.jsp";
}

5.7 solve the problem of Chinese garbled code

5.7.1 front end coding setting
  • JSP

    <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
    
  • html

    <meta charset="UTF-8">
    
5.7.2 Tomcat code setting of server
  • tomcat_home/conf/server.xml

    <Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" />
    
5.7.3 code setting in the project
  • Servlet class

    request.setCharacterEncoding("UTF-8");  //Must be before receiving the first data in the request
    
  • Spring MVC: Spring MVC provides a special coding filter, which we only need to use on the web Configure in XML:

    <filter>
        <filter-name>springmvcEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>springmvcEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

6, Date format processing

Customize the date format converter of spring MVC

6.1 custom Date Converter

/**
* Implement the Converter interface
*/
public class MyDateConverter implements Converter<String, Date> {

    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd");

    @Override
    public Date convert(String source) {

        Date date = null;
        try {
            if(source.matches("[0-9]{4}-[0-9]{2}-[0-9]{2}")){
                date = sdf1.parse(source);
            }else if(source.matches("[0-9]{4}/[0,1][0-9]/[0-3][0-9]")){
                date = sdf2.parse(source);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

}

6.2 configuring to spring MVC

 <mvc:annotation-driven conversion-service="conversionService"/>

<bean id="conversionService" 
      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.qfedu.converters.MyDateConverter"/>
        </set>
    </property>
</bean>

7, Unified exception handling

During the operation of our application system, the system may be abnormal (http status, exception in the program) due to the operation environment, user operation, insufficient resources, accidental exceptions of the program, etc; If there are exceptions in the system, these exceptions will be displayed in the web page through the browser, but it is not necessary to display these exception prompts to the user, and the user experience is not good. We can display specific web pages to the user for these exceptions.

7.1 unified handling of HTTP status exceptions

404 as an example

  1. Create status exception jump page 404 jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
        	The page you visited does not exist. Please check whether the URL you entered is normal.
        </body>
    </html>
    
  2. On the web Configure the mapping of exception status code and exception page in XML file

    <error-page>
        <error-code>404</error-code>
        <location>/404.jsp</location>
    </error-page>
    

7.2 unified handling of program exceptions

Various exception s thrown by the program: NullPointerException arithmetexception

  1. Servlet processing method:

    <error-page>
        <exception-type>java.lang.NullPointerException</exception-type>
        <location>/err.jsp</location>
    </error-page>
    
  2. Spring MVC processing method:

    @ControllerAdvice
    public class MyExceptionHandler {
    
        @ExceptionHandler(NullPointerException.class)
        public String nullHandler(Model model){
            model.addAttribute("tips","Null pointer");
            return "/err.jsp";
        }
    
        @ExceptionHandler(ArithmeticException.class)
        public String arithmeticHandler(Model model){
            return "/err.jsp";
        }
    
    }
    

8, Interceptor

8.1 introduction to interceptor

The interceptor provided by spring MVC is similar to the filter in servlet API. It can intercept the request of the controller and realize the related preprocessing and post-processing.

  • filter
    • As part of the Servlet specification, all web projects can use filters
    • Filter on Web XML (annotations can be used) to intercept all requests
  • Interceptor
    • Is the implementation of spring MVC framework, which can only be used in spring MVC projects
    • Interceptors are configured in the configuration file of spring MVC and will not intercept resources (mvc:resources) released by spring MVC

8.2 custom interceptors

  1. Create interceptor

    public class MyInterceptor implements HandlerInterceptor {
    
        /**
         * The preprocessing method of interceptor is executed before entering the controller method
         * return true Indicates release and enters the execution of the controller method
         * return false It means that the method will not be released through the browser, and the method will not respond directly
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("--------------------preHandle");
            //Example: if the submitted parameter does not contain bookId, it will not be released
            Enumeration<String> keys = request.getParameterNames();
            while(keys.hasMoreElements()){
                String key = keys.nextElement();
                if("bookId".equals(key)){
                    return true;
                }
            }
            response.setStatus(400);
            return false;
        }
    
        /**
         * Post processing method: after the controller method is executed, it is executed before responding to the browser
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("--------------------postHandle");
        }
    }
    
  2. Configuration Interceptor: in the configuration file of spring MVC

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/book/**"/>
            <mvc:exclude-mapping path="/book/list"/>
            <mvc:exclude-mapping path="/book/list2"/>
            <bean class="com.qfedu.handlers.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
    

8.3 interceptor chain

Multiple interceptors are configured to intercept the same controller request to form an interceptor chain, and multiple interceptors are executed according to the configuration order.

9, SSM integration

9.1 creating a web project

slightly

9.2 adding dependencies

9.2.1 MyBatis
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>
9.2.2 Spring
<properties>
  <spring.version>5.3.15</spring.version>
</properties>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</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>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>
9.2.3 integration
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>
9.2.4 others
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
</dependency>

9.3 configuration file

9.3.1 myabtis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>
9.3.2 druid.properties
druid.driver=com.mysql.cj.jdbc.Driver
druid.url=jdbc:mysql://localhost:3306/db_2111?characterEncoding=utf-8
druid.username=root
druid.password=@QFedu123

druid.pool.init=1
druid.pool.minIdle=3
druid.pool.maxActive=20
druid.pool.timeout=30000
9.3.3 spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd ">

    <!-- Declaration annotation configuration   -->
    <context:annotation-config/>
    <!-- Declared annotation scan range -->
    <context:component-scan base-package="com.qfedu"/>
    <!--  statement MVC Annotation configuration  -->
    <mvc:annotation-driven/>

    <!-- Database connection pool -->
    <context:property-placeholder location="classpath:druid.properties"></context:property-placeholder>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${druid.driver}"/>
        <property name="url" value="${druid.url}"/>
        <property name="username" value="${druid.username}"/>
        <property name="password" value="${druid.password}"/>
        <property name="maxActive" value="${druid.pool.maxActive}"/>
        <property name="minIdle" value="${druid.pool.minIdle}"/>
        <property name="initialSize" value="${druid.pool.init}"/>
        <property name="maxWait" value="${druid.pool.timeout}"/>
    </bean>

    <!--  SqlSessionFactory  -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:mappers/*Mapper.xml"/>
        <property name="typeAliasesPackage" value="com.qfedu.beans"/>
    </bean>

    <!--  MapperScannerConfigurer  -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.qfedu.dao"/>
    </bean>

    <!-- to configure Spring transaction management -->
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     	<property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- mvc Static resources -->
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/"></mvc:resources>
    <mvc:resources mapping="/pages/**" location="/pages/"></mvc:resources>

</beans>
9.3.4 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">

    <!--SpringMVC Front end controller-->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--  SpringMVC Coding filter  -->
    <filter>
        <filter-name>springmvcEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>springmvcEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

10, SSM integrated application

Case: Library Information Management

10.1 preparation

  • SSM integration configuration

  • Create book information table

    create table tb_books(
        book_id int primary key auto_increment,
        book_name varchar(100) not null,
        book_author varchar(20) not null,
        book_price decimal(10,2) not null,
        book_img varchar(100) ,
        book_date datetime not null,
        book_desc varchar(200)
    );
    
  • Case business process

    • Add books
    • Book list

10.2 book list function

10.2.1 implementation of database operation
  1. Create entity class

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class Book {
        
        private int bookId;
        private String bookName;
        private String bookAuthor;
        private double bookPrice;
        private String bookImg;
        private Date bookDate;
        private String bookDesc;
        
    }
    
  2. Create DAO interface and define operation method

    public interface BookDAO {
        
        public List<Book> selectBooks(); 
        
    }
    
  3. MyBatis mapping file configuration

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <!--namespace = Fully qualified name of the interface to be implemented-->
    <mapper namespace="com.qfedu.dao.BookDAO">
    
        <resultMap id="bookMap" type="Book">
            <id column="book_id" property="bookId"/>
            <result column="book_name" property="bookName"/>
            <result column="book_author" property="bookAuthor"/>
            <result column="book_price" property="bookPrice"/>
            <result column="book_img" property="bookImg"/>
            <result column="book_date" property="bookDate"/>
            <result column="book_desc" property="bookDesc"/>
        </resultMap>
    
        <select id="selectBooks" resultMap="bookMap">
            select book_id,book_name,book_author,book_price,book_img,book_date,book_desc
            from tb_books
        </select>
    
    </mapper>
    
10.2.2 implementation of business logic layer
  1. Create paging help class

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class PageBean<T> {
    
        private int pageNum;
        private int pageSize;
        private int pageCount;
        private int prePage;
        private int nextPage;
        private List<T> data;
    
    }
    
  2. Add MyBatis paging plug-in

    • Add dependency
    • Configure paging plug-in
  3. Create servcie interface

    public interface BookService {
    
        public PageBean listBooks(int pageNum, int pageSize);
    
    }
    
  4. Create a service implementation class

    @Service
    public class BookServiceImpl implements BookService {
    
        @Autowired
        private BookDAO bookDAO;
    
        public PageBean listBooks(int pageNum, int pageSize) {
            PageHelper.startPage(pageNum,pageSize);
            List<Book> books = bookDAO.selectBooks();
            PageInfo<Book> pageInfo = new PageInfo<Book>(books);
    
            int pageCount = pageInfo.getPages();
            int prePage = pageNum-1==0?1:pageNum-1;
            int nextPage = pageNum+1>pageCount?pageCount:pageNum+1;
            PageBean<Book> bookPageBean = new PageBean<Book>(pageNum, pageSize, pageCount, prePage, nextPage, pageInfo.getList());
    
            return bookPageBean;
        }
    }
    
10.2.3 business process realization
  1. Method for creating controller and processing book list request

    @Controller
    @RequestMapping("/book")
    public class BookController {
    
        @Autowired
        private BookService bookService;
    
        @RequestMapping("/list")
        public String list(@RequestParam(defaultValue = "1") int pageNum, 
                           @RequestParam(defaultValue = "5") int pageSize, Model model){
            PageBean pageBean = bookService.listBooks(pageNum, pageSize);
            model.addAttribute("pageBean",pageBean);
            return "/book-list.jsp";
        }
        
    }
    
  2. Create index JSP, click "book list" and send the synchronization request to book/list

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <table  style="width: 100%; height: 800px">
                <tr style="height: 100px; background: deepskyblue">
                    <td colspan="2">Library information management system</td>
                </tr>
            
                <tr style="height: 700px">
                    <td width="200" valign="top">
                        <ul>
                            <li><a href="book-add.jsp" target="mainFrame">Add books</a></li>
                            <li><a href="book/list" target="mainFrame">Book list</a></li>
                        </ul>
                    </td>
                    <td>
                        <iframe name="mainFrame" width="100%" height="700px"></iframe>
                    </td>
                </tr>
            </table>
        </body>
    </html>
    
  3. In book list JSP displays book list information

    • Add jstl dependency
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
        <head>
            <base href="${pageContext.request.contextPath}/">
            <title>Title</title>
        </head>
        <body>
            Book list page
            <table style="width: 96%;" align="center" border="1" cellspacing="0">
                <thead>
                    <tr>
                        <th>number</th>
                        <th>name</th>
                        <th>author</th>
                        <th>Price</th>
                        <th>picture</th>
                        <th>date</th>
                        <th>describe</th>
                        <th>operation</th>
                    </tr>
                </thead>
            
                <tbody>
                    <c:forEach items="${pageBean.data}" var="book">
                        <tr>
                            <td>${book.bookId}</td>
                            <td>${book.bookName}</td>
                            <td>${book.bookAuthor}</td>
                            <td>${book.bookPrice}</td>
                            <td><img src="${book.bookImg}" height="35"/></td>
                            <td>${book.bookDate}</td>
                            <td>${book.bookDesc}</td>
                            <td>
                                <a href="">delete</a>
                                <a href="">modify</a>
                            </td>
                        </tr>
                    </c:forEach>
            
                    <tr>
                        <td colspan="8" align="center">
                            <c:if test="${pageBean.pageNum == 1}">
                                <label style="color: gray">home page</label>
                                |
                                <label style="color: gray">previous page</label>
                            </c:if>
                            <c:if test="${pageBean.pageNum > 1}">
                                <a href="book/list?pageNum=1">home page</a>
                                |
                                <a href="book/list?pageNum=${pageBean.prePage}">previous page</a>
                            </c:if>
                
                            Current section ${pageBean.pageNum}page / common ${pageBean.pageCount}page
                
                            <c:if test="${pageBean.pageNum < pageBean.pageCount}">
                                <a href="book/list?pageNum=${pageBean.nextPage}">next page</a>
                                |
                                <a href="book/list?pageNum=${pageBean.pageCount}">Last page</a>
                            </c:if>
                            <c:if test="${pageBean.pageNum == pageBean.pageCount}">
                                <label style="color: gray">next page</label>
                                |
                                <label style="color: gray">Last page</label>
                            </c:if>
                        </td>
                    </tr>
                </tbody>
            </table>
        </body>
    </html>
    

10.3 add book function - file upload

Add book information, including pictures in books - involving file upload

10.3.1 implementation of database operation
  1. Define the add method in BookDAO

    public interface BookDAO {
    
        public List<Book> selectBooks();
    
        public int insertBook(Book book);
    
    }
    
  2. Configuration mapping file

    <insert id="insertBook">
        insert into tb_books(book_name,book_author,book_price,book_img,book_date,book_desc)
        values(#{bookName},#{bookAuthor},#{bookPrice},#{bookImg},#{bookDate},#{bookDesc})
    </insert>
    
10.3.2 implementation of business logic layer
  1. Define and add business methods in BookService interface

    public interface BookService {
    
        public PageBean listBooks(int pageNum, int pageSize);
        
        public int addBook(Book book);
    
    }
    
  2. Add book business in BookServiceImpl implementation class

    @Service
    public class BookServiceImpl implements BookService {
    
        @Autowired
        private BookDAO bookDAO;
    
        public PageBean listBooks(int pageNum, int pageSize) {
           //....
            return bookPageBean;
        }
    
        public int addBook(Book book) {
            int i = bookDAO.insertBook(book);
            return i;
        }
    }
    
10.3.3 business process realization
  1. Flow chart of asynchronous image upload

  1. Design book add jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <form action="" method="post">
                <p>name:<input type="text" name="bookName"/></p>
                <p>author:<input type="text" name="bookAuthor"/></p>
                <p>Price:<input type="text" name="bookPrice"/></p>
                <p>picture:
                    <br/>
                    <img src="" height="100" id="imgTag"/><br/>
                    <input type="file" id="bookImgFile"/>
                    <input type="hidden" name="bookImg" id="bookImg"/>
                </p>
                <p>date:<input type="text" name="bookDate"/></p>
                <p>describe:<input type="text" name="bookDesc"/></p>
                <p><input type="submit" value="Submit"/></p>
            </form>
        </body>
    </html>
    
  2. When selecting a picture, ajax is triggered to asynchronously submit the picture information to the controller

    <img src="" height="100" id="imgTag"/><br/>
    <input type="file" onchange="uploadImg()" id="bookImgFile"/>
    <input type="hidden" name="bookImg" id="bookImg"/>
    
    <script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        function uploadImg(){
            //Front end submitted pictures: 1 Form post submission, 2 Uncompressed submission
            var file = $("#bookImgFile")[0].files[0];
            var formData = new FormData();
            formData.append("bookImgFile",file);
            $.ajax({
                url:"file/upload",
                type:"post",
                data:formData,
                processData:false,
                contentType:false,
                success:function(res){
                    console.log(res);
                }
            });
        }
    </script>
    
  3. Create a controller to receive uploaded pictures

    • Import the jar required for file upload

      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.4</version>
      </dependency>
      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
      </dependency>
      
    • Spring MVC file upload configuration: upload the parser in the spring configuration file configuration file

      <bean id="multipartResolver" 
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <property name="maxUploadSize" value="10240000"/>
          <property name="maxInMemorySize" value="102400"/>
          <property name="defaultEncoding" value="utf-8"/>
      </bean>
      
    • Receive files at controller

      @Controller
      @RequestMapping("/file")
      public class FileController {
      
          @ResponseBody
          @RequestMapping("/upload")
          public Map<String, String> upload(MultipartFile bookImgFile, HttpServletRequest request) throws IOException {
              //file save
              String originalFilename = bookImgFile.getOriginalFilename();
              String ext = originalFilename.substring(originalFilename.lastIndexOf("."));  
              String fileName = UUID.randomUUID().toString().replace("-","")+ext;
      
              String dir = request.getServletContext().getRealPath("images"); 
              bookImgFile.transferTo( new File(dir+"/"+fileName));
      
              Map<String, String> map = new HashMap<String, String>();
              map.put("filePath","images/"+fileName);
              return map;
          }
      
      }
      
    1. In book add JSP sets the image path returned by the file upload request to the src attribute of the img tag and the value attribute of the hidden field

      <script type="text/javascript">
          function uploadImg(){
              //Front end submitted pictures: 1 Form post submission, 2 Uncompressed submission
              var file = $("#bookImgFile")[0].files[0];
              var formData = new FormData();
              formData.append("bookImgFile",file);
              $.ajax({
                  url:"file/upload",
                  type:"post",
                  data:formData,
                  processData:false,
                  contentType:false,
                  success:function(res){
                      if(res.code == "200"){
                          $("#imgTag").attr("src",res.filePath);
                          $("#bookImg").val(res.filePath);
                      }
                  }
              });
          }
      </script>
      
    2. Create a method to save books in BookController (create tips.jsp prompt page)

      @RequestMapping("/add")
      public String add(Book book,Model model){
          int i = bookService.addBook(book);
          String tips = i>0? "<label style='color:green'>Added successfully!</label>":
          "<label style='color:red'>Failed to add!</label>";
          model.addAttribute("tips",tips);
          return "/tips.jsp";
      }
      
    3. book-add.jsp submits the book information to book/add (ensure that the name attribute of the input box is consistent with the attribute name of the controller Book object)

      <form action="book/add" method="post">
          <p>name:<input type="text" name="bookName"/></p>
          <p>author:<input type="text" name="bookAuthor"/></p>
          <p>Price:<input type="text" name="bookPrice"/></p>
          <p>picture:
              <br/>
              <img src="" height="100" id="imgTag"/><br/>
              <input type="file" onchange="uploadImg()" id="bookImgFile"/>
              <input type="hidden" name="bookImg" id="bookImg"/>
          </p>
          <p>date:<input type="text" name="bookDate"/></p>
          <p>describe:<input type="text" name="bookDesc"/></p>
          <p><input type="submit" value="Submit"/></p>
      </form>
      
    4. tips. The JSP page displays prompt information

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          	${tips}
          </body>
      </html>
      

";
model.addAttribute("tips",tips);
return "/tips.jsp";
}
```

  1. book-add.jsp submits the book information to book/add (ensure that the name attribute of the input box is consistent with the attribute name of the controller Book object)

    <form action="book/add" method="post">
        <p>name:<input type="text" name="bookName"/></p>
        <p>author:<input type="text" name="bookAuthor"/></p>
        <p>Price:<input type="text" name="bookPrice"/></p>
        <p>picture:
            <br/>
            <img src="" height="100" id="imgTag"/><br/>
            <input type="file" onchange="uploadImg()" id="bookImgFile"/>
            <input type="hidden" name="bookImg" id="bookImg"/>
        </p>
        <p>date:<input type="text" name="bookDate"/></p>
        <p>describe:<input type="text" name="bookDesc"/></p>
        <p><input type="submit" value="Submit"/></p>
    </form>
    
  2. tips. The JSP page displays prompt information

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>Title</title>
        </head>
        <body>
        	${tips}
        </body>
    </html>
    

Topics: Java Javascript Front-end Spring