springboot advanced, paging plug-in pageHelper, Swagger integration, log

1. Course review

1. Springboot simplifies the process of building and using springboot
2, @ SpringBootApplication composite annotation
@Configuration is equivalent to xml @Bean in the past
@EnableAutoConfiguration automatically integrates third-party jar s
@All classes marked with spring in the same package or child package of ComponentScan will be handed over to IOC container management @ Controller @RestController @Service @Repository @Component
3,SpringApplication.run() initializes ApplicationContext initializes listener initializes Runners sorts all Runners and executes them in order
4. Spring boot integrates mybatis

2. Key points of this chapter

springboot connection pool (monitoring function)
springboot log configuration
springboot integration PageHelper
springboot integrates swagger(postman)

3. Specific contents

3.1 consolidated connection pool

Add support

  <!-- druid Database connection pool -->
     If it is druid The new version requires two packages:

Modify configuration

#spring.datasource.druid.driver-class-name=oracle.jdbc.driver.OracleDriver can be configured or not. Alibaba's database connection pool will automatically search through url
#Whether to cache preparedStatement, that is, PSCache. PSCache greatly improves the performance of databases that support cursors, such as oracle.
#In mysql5 There is no PSCache function in versions below 5. It is recommended to turn it off.
#How often is the configuration interval detected? Idle connections that need to be closed are detected in milliseconds
#Configure the minimum lifetime of a connection in the pool, in milliseconds
#Configuration extension: filter for monitoring statistics: filter for stat log: log4j filter for defending sql injection: Wall
# Merge monitoring data of multiple DruidDataSource

Monitoring configuration:

import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

 * @ fileName:DruidConfig
 * @ description:
 * @ author:zhz
 * @ createTime:2021/7/14 20:33
 * @ version:1.0.0
public class DruidConfig {
     *  It mainly realizes the configuration processing of WEB monitoring
    public ServletRegistrationBean druidServlet() {
        // Now you need to perform the configuration processing of druid monitoring
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(
                new StatViewServlet(), "/druid/*");
        // White list. Multiple are separated by commas. If allow is not configured or empty, all accesses are allowed
        servletRegistrationBean.addInitParameter("allow", ",");
        // Blacklist, multiple are separated by commas (when they exist together, deny takes precedence over allow)
        servletRegistrationBean.addInitParameter("deny", "");
        // Console admin user name
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        // Console management password
        servletRegistrationBean.addInitParameter("loginPassword", "tiger");
        // Can I reset the data source and disable the "Reset All" function on the HTML page
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean ;

     *Configure the filter WebStatFilter to complete the statistics of all url requests
     * @return
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean() ;
        filterRegistrationBean.setFilter(new WebStatFilter());
        //All requests are monitored and processed
        //Add format information that you do not need to ignore
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.css,/druid/*");
        return filterRegistrationBean ;

     * Load druidDataSource
     * @return
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    public DataSource druidDataSource() {
        return new DruidDataSource();


Request address:

3.2 springboot log configuration:

springboot log address: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging
Introduction to common logs:


It is an open source project of Apache. By using Log4j, we can control that the destination of log information transmission is console, file, database, etc; We can also control the output format of each log; By defining the level of each log information, we can control the log generation process in more detail.
Log4j has seven different log levels, from low to high: TRACE, DEBUG, INFO, WARN, ERROR, FATAL and OFF. If it is configured as OFF level, it means that the log is closed.
Log4j supports two formats of configuration files: properties and xml. It contains three main components: Logger, appender and Layout.
Detailed configuration:


Spring Boot1. Log4j is not supported in version 4 and later, and log4j has not been updated for a long time. Now there are many other log frameworks that have improved log4j, such as SLF4J, Logback, etc
Detailed configuration:


SLF4J, the Simple Logging Facade for Java, is not a specific logging solution, but provides some Java logging API s through the Facade Pattern, which only serves a variety of logging systems. According to the official statement, SLF4J is a simple Facade for logging system, which allows end users to use the desired logging system when deploying their applications.


Logback, a "reliable, universal, fast and flexible Java logging framework", is currently divided into three modules: logback core, logback classic and logback access. Logback core is the basic module of the other two modules. Logback classic is an improved version of log4j. In addition, logback classic fully implements SLF4J API, so that you can easily change to other logging systems, such as log4j or JDK Logging.
springboot uses logback configuration by default

Apache Commons Logging

Apache Commons Logging, formerly known as Jakarta Commons Logging (JCL), provides a log interface, which is lightweight and independent of specific log implementation tools. It provides a simple log operation abstraction for Middleware / log tool developers, and allows program developers to use different specific log implementation tools. Users are assumed to be familiar with the higher-level details of some logging implementation tool. The interface provided by JCL simply packages some other logging tools, including Log4J, Avalon LogKit, and JDK 1.4 +. This interface is closer to the implementation of Log4J and LogKit.

Log usage in springboot project class

 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 private   Logger log = LoggerFactory.getLogger(DeptController.class);

springboot directly configures the log in properties:

#Log related configuration
#Path to the configuration log file
#Configure the log file name. If this attribute is not configured, the default file name is spring Log windows: path and name cannot be configured at the same time. Only name is effective for notification configuration
#Configure log level
#Customize console log output format
    #%d{HH:mm:ss.SSS} - log output time
    #%thread -- the name of the process that outputs the log, which is very useful in Web applications and asynchronous task processing
    #%-5level -- log level, with 5 characters aligned to the left
    #%logger - the name of the log exporter
    #%msg -- log message
    #%n -- newline character of platform
logging.pattern.console=%d{yyyy/MM/dd} [%thread] %-5level %logger- %msg%n 
#Custom file log output format
logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
#mybatis configuration log

logback configuration of springboot

The configuration log does not need to import jar s. The log package has been imported in the parent project. The specific location is as follows:
Spring boot starter parent ---- parent package - > spring boot dependencies ---- parent package - > spring boot dependencies ----- search ----- > spring boot starter logging - click in ----- > you can see the log package: logback classic, log4j to slf4j

Create logback under resources Log-back or spring.xml XML, copy the configuration

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--Define the storage address of the log file LogBack Relative paths are used in the configuration of-->
    <property name="LOG_HOME" value="D:/projects/log" />
    <!-- console output  -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--Format output:%d Indicates the date,%thread Represents the thread name,%-5level: The level is displayed 5 characters wide from the left%msg: Log messages,%n Is a newline character-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    <!-- Generate log files on a daily basis -->
    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--The file name of the log file output-->
            <!--Log file retention days-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--Format output:%d Indicates the date,%thread Represents the thread name,%-5level: The level is displayed 5 characters wide from the left%msg: Log messages,%n Is a newline character-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <!--Maximum size of log file-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    <!--myibatis log configure-->
    <logger name="com.apache.ibatis" level="DEBUG"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    <!-- Log output level
    Levels are inclusive relationships, which means that if you set the log level to trace,Logs greater than or equal to this level will be output.
    trace:  It's tracking, it's program advancement. Below, you can write a trace Output, so trace There should be a lot, but it doesn't matter. We can set the minimum log level to prevent it from being output.
    debug:  For debugging, I usually only use this as the lowest level, trace Not at all. It's used when there's no way eclipse perhaps idea of debug Function is good.
    info:  Output the information you are interested in or important, which is most used.
    warn:  Some messages are not error messages, but they should also give some hints to programmers, similar to eclipse The verification of the code in is not a problem error and warn(It's not a mistake, but please pay attention, such as the following depressed Method).
    error:  Error message. They also use more.
    fatal:  The level is relatively high. Major error. At this level, you can stop the program directly. Is it an error that should not occur! Don't be so nervous. It's actually a matter of degree.
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    <!--Log to database asynchronously -->
    <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">-->
    <!--<!–Log to database asynchronously –>-->
    <!--<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">-->
    <!--<!–Connection pool –>-->
    <!--<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">-->

3.3 springboot integration shiro

springboot application Properties configuration
springboot accesses templates configuration (or creates resources to place HTML)
Before integration, you need to explain the usage of @ Configuration and @ Bean, otherwise the integration code cannot be understood.

@Configuration can be understood as the label and annotation in xml when using spring. It is just like a spring xml configuration file we declared earlier. This class is called configuration class
@A Bean can be understood as a label in the xml when using spring, which is marked on the method. The return value of the method is to inject a Bean into the springIOC container The return value is equivalent to the class attribute of the Bean tag in the xml file If @ Bean is configured, value is equivalent to id attribute; if not configured, the name of the method is equivalent to id attribute

package com.aaa.sbms.config;

import com.aaa.sbms.entity.Dept;
import com.aaa.sbms.entity.Emp;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

 * fileName:MyConfig
 * description:
 * author:zz
 * createTime:2019/11/26 15:48
 * version:1.0.0
public class MyConfig {

     * Equivalent to the past
     *  <bean name="emp"   class="com.aaa.sbms.entity.Emp"  >
     * @return
    public Emp emp(@Qualifier("d1") Dept d){
        Emp emp = new Emp();
        return emp;

    public Dept dept(){
        Dept dept =new Dept();
        return dept;
package com.aaa.sbms;

import com.aaa.sbms.entity.Emp;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement  //Open annotated transaction
public class SbmShiroApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(SbmShiroApplication.class, args);
		Emp emp =(Emp)applicationContext.getBean("emp");


After getting familiar with the above knowledge points, integrate shiro
1. Introduction package:


Or use:


2. Write ShiroConfig

package com.aaa.sbm.configuration;

import com.aaa.sbm.util.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

 * fileName:ShiroConfiguration
 * description:
 * author:zz
 * createTime:2020/10/13 10:39
 * version:1.0.0
@Configuration  // Equivalent to spring Shiro config xml
public class ShiroConfiguration {

     * shiro The filter factory instance configuration intercepts all requests for processing
     * @return
    @Bean // <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    public ShiroFilterFactoryBean shiroFilter(){
        //Instantiate object
         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
         //Make securityManager effective
         //Set login path for unauthenticated jump
        //Define the request path to release or intercept
        Map<String, String> urlMap = new LinkedHashMap<>(); //In the order of addition
        //Filter free address
        //Filter address
         return shiroFilterFactoryBean;

     * Instantiate SecurityManager
     * @return
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =new DefaultWebSecurityManager();
        return  securityManager;

     *Instantiate custom Realm class
     * @return
    public MyRealm myRealm(){
        MyRealm myRealm =new MyRealm();
        //Set value algorithm class
        return myRealm;

     *Instantiate encryption algorithm class
     * @return
    public HashedCredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //Set value encryption algorithm name
        //Set the number of hash es
           return hashedCredentialsMatcher;

     * The main function is to use the callback function of the bean post processor to generate corresponding agents for other beans in the ioc container according to the advisor configured by the ioc container
     * @return
    @ConditionalOnMissingBean  //Ensure that the bean is registered at the bottom layer once
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        return defaultAAP;

     * Permission filtering at the method level is used to support shiro annotation. After configuration, shiro identifies @ RequiresPermissions
     * @param securityManager
     * @return
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        return authorizationAttributeSourceAdvisor;


package com.aaa.sm.config;

import com.aaa.sm.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

 * fileName:MyShiroRealm
 * description:
 * author:zz
 * createTime:2019/11/14 10:38
 * version:1.0.0
public class MyShiroRealm extends AuthorizingRealm {

    private UserService userService;

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //Add roles and permissions
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //Add role
            //add permission
            for (Permissions permissions : role.getPermissions()) {
        return simpleAuthorizationInfo;

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //Get user name
        Object userName = authenticationToken.getPrincipal();
        Map map = new HashMap();
        //Query list by user name
        List<Map> userMapList = userService.getListByParam(map);
            Map userMap = userMapList.get(0);
            return new SimpleAuthenticationInfo(userMap.get("USER_NAME")+"",
        }else {
            throw new AccountException();

Method configuration:

    public String admin() {
        return "admin success!";

    public String index() {
        return "index success!";

    public String add() {
        return "add success!";

4. Write the login page and functions for testing

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>User login</title>
    <script src="/js/jquery-3.4.1.min.js"></script>
        $(function () {
            //Bind login button click event
            $("#btn").click(function () {
                    success:function (data) {
                           //Jump to home page
                           $("#errorDiv").html(" wrong user name or password! ");
                    error:function () {
     <div style="color: red;" id="errorDiv"></div>
     user name:<input type="text" id="userN">
     password:<input type="text" id="passW">
         <input type="button" id="btn" value="Sign in">

3.4 mybatis paging plug-in pageHelper


1. Add jar package

   <!-- Paging plug-in pagehelper -->       
 <!-- Paging plug-in pagehelper -->

2. Add springboot configuration


 #Paging plug-in
#The helperDialect property to specify which dialect the paging plug-in uses
#When this parameter is set to true, the first page will be queried when pagenum < = 0, and the last page will be queried when pagenum > pages (exceeds the total).
#It supports the transfer of paging parameters through Mapper interface parameters. The default value is false. The paging plug-in will automatically take values from the parameter values of the query method according to the fields configured in params above. When an appropriate value is found, it will automatically page.
#This parameter is added to configure parameter mapping, which is used to take values from objects according to attribute names

3. Specific use
Different from previous controller s

//Set the current page number and display quantity per page PageHelper startPage(Integer.valueOf(map.get(“pageNo”)+""),Integer. valueOf(map.get(“pageSize”)+""));
//Wrap the results with PageInfo
PageInfo pageInfo =new PageInfo(newsService.getList());

     * Paging Department query
     * @param map
     * @return
    public Object page(@RequestParam Map map){
        int pageNo = Integer.valueOf(map.get("pageNo")+"");
        int pageSize = Integer.valueOf(map.get("pageSize")+"");
        //Initialize configuration
        PageInfo<Map> pageInfo = new PageInfo<Map>(deptService.getList());
       //If easyui is used, it can be encapsulated in this way. Other frameworks can parse according to pageInfo
        Map tmap  = new HashMap();
        return tmap;

3.5 spring boot integrates thymeleaf (similar to jsp template)

Thymeleaf is a modern server-side Java template engine for Web and stand-alone environments.
Thymeleaf's main goal is to bring elegant natural templates to your development workflow - HTML can be displayed correctly in the browser or work as a static prototype, so as to strengthen cooperation among the development team.
Thymeleaf has modules for the Spring Framework, extensive integration with your favorite tools, and the ability to plug in your own functions. Thymeleaf is ideal for modern HTML5 JVM Web development - although it still has a lot of work to do.
3.5.1 introducing jar:

 <!-- thymeleaf -->

3.5.2 application.properties add configuration

# thymeleaf
#Configure the location of the thymeleaf template
#Configure thymeleaf template suffix
#Configure the encoding of thymeleaf documents
#Content type
#Template format
#The cache line is to close the page cache, otherwise we may not be able to see the changed content in time after changing the page. The default is true

3.5.3 background binding value

               org.springframework.ui.Model   + String 

3.5.4 use of page thymeleaf label


<html lang="en" xmlns:th="http://www.thymeleaf.org">
	           <tr th:each="dept:${deptList}">
	           <td th:text="${dept.deptNo}"> </td>
	          <a th:href="@{/deptTh/toUpdate(deptNo=${dept.deptNo})}">modify</a>
	          <a th:href="'javascript:del('+${dept.deptNo}+')'">delete</a>
	          <input type="hidden" name="deptNo" value="deptNo" th:value="${dept.deptNo}"/>
	   <input type="text" name="dname"   th:value="${dept.dname}"  >

3.6 springboot integration swagger

Simplify API development for users, teams and enterprises with Swagger open source and professional toolset. Learn how Swagger can help you design and document APIs on a large scale.
The powerful function of Swagger tool begins with the OpenAPI specification - the industry standard for RESTful API design
Open source, free, professional
1. jar dependency

  <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->

2. Spring boot integrates swagger configuration

    package com.aaa.sbm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

 * fileName:SwaggerConfig
 * description:
 * author:zz
 * createTime:2020/1/11 14:50
 * version:1.0.0
public class SwaggerConfig {

     * Create a dock
     * @return
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                //. enable (false) / / swagger cannot be accessed
                //Configure how to scan interfaces
                //Path filtering

     * apiInfo
     * @return
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot Used in Swagger2 structure RESTful APIs")
                .description("Please pay more attention http://www.baidu.com")

3. Start swagger
4. Optional configuration

     @ApiOperation("Department deletion")
      @ApiParam("Department delete parameter")

5. Test

Tags: Java Spring Boot swagger

Posted by bryanzera on Tue, 19 Apr 2022 08:52:14 +0930