Spring boot web application practice

I have been using springboot for some time, and I always want to make a summary. Before the Department training, I just had to sort out a related document. Because of the outbreak, I stayed at home every day in order not to cause any disturbance to the country and society, and I sent out the articles sorted out before when I was free. The articles are not detailed enough. I refer to many articles, and the reference link is at the end of the article.

1 Introduction

SpringBoot is a new and open-source lightweight framework developed by the Pivotal team in 2013 and released in April 2014. It is designed based on Spring 4.0. It not only inherits the original excellent features of Spring framework, but also simplifies the whole process of building and developing Spring application by simplifying configuration. In addition, through integrating a large number of frameworks, Spring boot solves the problems of version conflicts of dependent packages and instability of references.

The features of SpringBoot are as follows:

(1) You can create independent Spring Applications, and based on their Maven or Gradle plug-ins, can create executable JARs and WARs;

(2) Embedded Servlet containers such as Tomcat or Jetty;

(3) Provides an automatically configured "starter" project object model (POMS) to simplify Maven To configure;

(4) Configure the Spring container as automatically as possible;

(5) Provide ready features such as metrics, health checks, and external configurations;

(6) There is absolutely no code generation and XML configuration is not required;

Differences between SpringBoot and SpringMvc:

Spring is an "engine";

Spring MVC is an MVC framework based on spring;

Spring Boot is a set of rapid development integration package based on spring conditional registration.

Some common notes of SpringBoot:

(1) The @ RestController and @ Controller specify a class as the annotation of the Controller and explain the differences

(2) @ RequestMapping method level mapping annotation, which is familiar to a small partner who has used Spring MVC

(3) The @ EnableAutoConfiguration and @ SpringBootApplication are class level annotations. The correct spring configuration is automatically guessed based on the jar that maven relies on. As long as the spring boot starter web dependency is introduced, the Spring MVC and tomcat containers are automatically configured by default

(4) The @ Configuration class level annotation is generally used to identify the class where the main method is located and complete the initialization of metadata bean s.

(5) The @ ComponentScan class level annotation automatically scans and loads all Spring components, including Bean injection, which is generally used on the class where the main method is located

(6) The @ ImportResource class level annotation, when we have to use an xml Configuration, @ ImportResource and @ Configuration are used to identify the class of this file resource.

(7) The @ Autowired annotation, usually combined with the @ ComponentScan annotation, automatically injects a Service or Dao level Bean

(8) The @ Component class level annotation is used to identify a Component. For example, if I set a filter by myself, Spring Boot will recognize it correctly only after this annotation is needed.

(9) Transaction annotation is OK. Method is method transaction and class is class transaction.

2 actual combat

2.1 project construction

Create maven project and introduce dependency

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
    <relativePath></relativePath>
</parent>
<dependencies>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-web</artifactId>
    </dependency>
<dependencies>

Create the application.properties file under resource

#Encoding settings
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
spring.http.encoding.enabled=true
spring.messages.encoding=UTF-8
# tomcat config
server.tomcat.accept-count=1000
server.tomcat.max-threads=500
# session timeout, in seconds
server.servlet.session.timeout=1800

#Current application http port
server.port=8787
#Access address
#server.servlet.context-path=/spring-boot-web-demo

Create startup class

@SpringBootApplication
public class Application {
    private static Logger logger = LoggerFactory.getLogger(Application.class);
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        application.run(args);
        logger.info("Startup success");
    }
}

Create Controller class

@RestController
@RequestMapping("/api/demo")
public class DemoController {
   @RequestMapping(value = "/hello", method = RequestMethod.GET)
   public String hello() {
      return "hello world";
   }
}

Run the Application class, and then open the browser to access

2.2 configuration

2.2.1 local configuration

The Spring program will load the application.yml and application.properties configuration files from the following paths according to priority. At the same time, it will load the application.yml file first and then the application.properties configuration file.

(1) / config directory under the current directory

(2) Current directory

(3) / config directory in classpath

(4) classpath and directory

Therefore, it's easy to add configuration files outside. Create a new config folder in the directory where the jar is located, and then put the configuration files in it, or directly put the configuration files in the jar directory.

At the same time, different configurations can be read according to different environments of Profile, and a configuration file can be set for different environments, for example:

  • The configuration of dev environment is in application-dev.properties
  • The configuration of test environment is in application-test.properties

Specify which file to use in application.properties

spring.profiles.active = dev

2.2.2 user defined configuration file

2.2.3 remote configuration

At present, the popular remote configurations include spring official spring cloud config, apollo of Ctrip and ali nacos, which have their own advantages. Reference links 5, 6, 7

2.3 Swagger2 integration

Nowadays, front-end and back-end separation has gradually become a standard development method for Internet projects. The front-end and back-end are handed over to different personnel for development, but the communication cost in project development also increases. This part of communication cost mainly lies in the communication between front-end developers and back-end developers on the web Api interface. Swagger 2 can solve this problem very well. It can Generate Api interface documents dynamically, reduce communication cost and promote efficient development of the project.

pom.xml add dependency

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

Swagger configuration class

@Configuration
@EnableSwagger2
public class SwaggerConfigurer {
   @Bean
   public Docket createRestApi() {
      return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select().apis(RequestHandlerSelectors.basePackage("com.linewell.license"))
            .paths(PathSelectors.any())
            .build();
   }
   private ApiInfo apiInfo() {
      ApiInfoBuilder builder = new ApiInfoBuilder();
      builder.title("spring-boot-demo");
      builder.description("spring-boot-demo rest api File");
      builder.version("1.0");
      return builder.build();
   }
}

Use related notes in development

@Api(tags = {"DEMO Related interfaces"})
@RestController
@RequestMapping("/api/demo")
public class DemoController {
   @ApiOperation("HELLO Interface")
   @RequestMapping(value = "/hello", method = RequestMethod.GET)
   public String hello() {
      return "hello world";
   }
}

Launch project, open browser to view interface information

2.4 Mybatis integration

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.4</version>
</dependency>
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.1.5</version>
</dependency>
<!--Paging plugins-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.10</version>
</dependency>

application.properties add database related configuration

#Database related configuration
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo
spring.datasource.username=root
spring.datasource.password=123456
#maximum connection
spring.datasource.tomcat.max-active=20
#Maximum number of idle
spring.datasource.tomcat.max-idle=8
#Minimum number of idle
spring.datasource.tomcat.min-idle=8
#Number of initial connections
spring.datasource.tomcat.initial-size=10
#Verify the idle connection in the pool, and recycle the connection if the verification fails
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mybatis
mybatis.type-aliases-package=com.spring.boot.demo.model
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

If you want to view sql logs, you need to configure the corresponding mapper log level to debug in logback

<logger name="com.spring.boot.demo.mapper" level="DEBUG" />

Open transaction

2.5 Security integration

SpringBoot is highly integrated with Security, and only primary usage is covered here.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Security configuration

2.6 component packaging

2.6.1 filter

Method 1:

Mode two:

2.6.2 interceptor

2.6.3 event listener

Method 1:

Mode two:

Create a new META-INF/spring.factories file under the resource path, and the configuration file will be automatically loaded by spring boot when it is loaded.

2.6.4 timer

Add @ EnableScheduling annotation in Application

Define task class

@Component
public class CustomTask {
    @Scheduled(cron = "0/15 * * * * ? ")
    public void taskDemo(){
        //Task begins
    }
}

2.11 health examination

Spring boot's monitoring artifact, the activator, is very simple to integrate and easy to use, that is, to simply call and view the rest interface, which can be used in the monitoring environment with low requirements.

2.11.1 integration

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Add a new configuration in the application.properties configuration file

#Monitoring related configuration
#Set the application root path for monitoring access. The default is / actor
management.endpoints.web.base-path=/actuator
#Expose monitoring provider, default is / health and / info
management.endpoints.web.exposure.include=*
#Explicit shielding monitoring provider
#management.endpoints.web.exposure.exclude=env,metrics
#Open close application endpoint, not recommended
management.endpoint.shutdown.enabled=false
#Show health details
management.endpoint.health.show-details=always

To start a project, it should be noted that since the general monitoring can be accessed without login, the corresponding url of monitoring should be filtered out in the security configuration.

Start the project and monitor the corresponding url through browser access

2.11.2 user defined application information

Add the following configuration in application.properties

#Basic information of application
info.app.name=spring boot demo
info.company.name=www.linewell.com
info.build.artifactId=$project.artifactId$
info.build.version=$project.version$
info.build.time=$project.build.time$

Access in browser

2.11.3 user defined detection endpoint

The actor comes with some detection endpoints, such as mysql, etc., but sometimes the project needs to customize some detection endpoints, but if you want to use the actor, you need to customize the detection endpoint.

@Component
public class CustomHealthIndicator extends AbstractHealthIndicator {

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        builder.status(Status.UP);
        builder.withDetail("message" ,"custom health indicator");
    }
}

Access in browser

2.12 unit test

Spring boot's unit test is simple, just add the following dependencies to pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

2.12.1 Service layer test

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserDao userDao;

    @Test
    public void getUser(){
        User user = userDao.getUserByUserName("admin");
        System.out.println(user.getUserName());
    }

}

2.12.2 Controller layer test

@RunWith(SpringRunner.class)
@SpringBootTest
public class MenuControllerTest {
    @Autowired
    private WebApplicationContext wac;
    @Autowired
    private UserDao userDao;
    private MockMvc mvc;
    private MockHttpSession session;
    @Before
    public void setupMockMvc(){
//Initialize MockMvc object
        mvc = MockMvcBuilders.webAppContextSetup(wac).build(); 
        session = new MockHttpSession();
        User user = userDao.getUserByUserName("admin");
        //The interceptor will determine whether the user is logged in, so a user is injected here
        session.setAttribute("LOGIN-INFO",user);
    }

    @Test
    public void getMenus() throws Exception{
        mvc.perform(MockMvcRequestBuilders.get(AipVersionConstant.API + AipVersionConstant.API_VERSION_01 + "/menu")
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .session(session))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andDo(MockMvcResultHandlers.print());
    }
}

1.mockMvc.perform performs a request

2. Mockmvrequestbuilders. Get ("/ user/1") constructs a request, and the post request uses the. Post method

3. The content type (mediatype. Application? JSON? Utf8) represents that the data format sent by the sender is application/json;charset=UTF-8

4. Accept (mediatype. Application? JSON? Utf8) means that the data type the client wants to accept is application/json;charset=UTF-8

5. Inject a session (session) so that the interceptor can pass the

6.ResultActions.andExpect add assertions after execution

7. Resultactions. Andexpect (mockmvresultmatchers. Status(). Isok()) method to see if the status response code of the request is 200. If not, throw an exception. The test fails

8. Andexpect (mockmvresultmatchers. jsonPath ("$. Author"). value("Dudu MD independent blog")) here jsonPath is used to get whether the comparison of the author field is Dudu MD independent blog. If not, the test fails

9.ResultActions.andDo add a result processor to indicate what to do with the result. Use MockMvcResultHandlers.print() to output the whole response result information

2.13 static resources

The default static file path of SpringBoot is in the resource/static folder. If you want to change the static resource path, you can add or modify the following configuration in application.properties. Multiple paths are separated by commas.

#Static resource path
spring.resources.static-locations= classpath:./static

2.14 pack

Spring boot has built-in Tomcat or Jetty, so it is recommended to use jar package for packaging, but it also supports the way of War package for packaging, depending on the needs of each project.

2.14.1. Jar packaging

In general, jar packaging will cooperate with Maven assembly plugin for packaging.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>com.linewell.license.demo.Application</mainClass>
                <layout>ZIP</layout>
                <includes>
                    <!--<include>
                        <groupId>nothing</groupId>
                        <artifactId>nothing</artifactId>
                    </include>-->
                    <include>
                        <groupId>com.linewell.license.platform</groupId>
                        <artifactId>license-platform-common-mybatis-mapper</artifactId>
                    </include>
                    <include>
                        <groupId>com.linewell.license.platform</groupId>
                        <artifactId>license-platform-common-model</artifactId>
                    </include>
                </includes>
            </configuration>
        </plugin>
        <!-- take jar Package and external configuration(zip,tar,tar.gz etc.) -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <skipAssembly>${assembly.skip.param}</skipAssembly>
                <!--jar Package name -->
                <finalName>${project.artifactId}</finalName>
                <descriptors>
                    <descriptor>package.xml</descriptor>
                </descriptors>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <includes>
                <include>config/**</include>
                <include>mybatis/**</include>
                <include>logback-spring.xml</include>
                <include>META-INF/spring.factories</include>
                <!-- If it is war Package to annotate the contents of static resources -->
                <include>static/**</include>
            </includes>
        </resource>
    </resources>
</build>

Create a new package.xml file in the following directory

<?xml version="1.0" encoding="UTF-8"?>
<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>package</id>
    <formats>
        <format>tar.gz</format>
    </formats>
    <!-- Change to false Two layers of the same directory will not appear -->
    <includeBaseDirectory>false</includeBaseDirectory>  
    <fileSets>
        <!-- bin file -->
        <fileSet>
            <directory>src/main/bin</directory>
            <outputDirectory>./</outputDirectory>
        </fileSet>
        <!-- configuration file -->
        <fileSet>
            <directory>target/classes/config</directory>
            <outputDirectory>./config</outputDirectory>
            <includes>
                <include>application.yml</include>
            </includes>
        </fileSet>
        <!-- Front end engineering documents -->
        <fileSet>
            <directory>/target/classes/static</directory>
            <outputDirectory>./static</outputDirectory>
        </fileSet>

        <!-- Compiled the project itself jar Files, packing in zip Root directory of the file -->
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>${file.separator}</outputDirectory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>
    </fileSets>
    <dependencySets>          
      <dependencySet>              
         <outputDirectory>libs</outputDirectory>              
         <scope>runtime</scope>              
         <excludes>
                <exclude>com.linewell.license:*</exclude>
                <exclude>com.linewell.license.platform:*</exclude>
         </excludes>
      </dependencySet>      
   </dependencySets>  
</assembly>

2.14.2. War packaging

Removing tomcat dependency of spring boot in pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- If it's packed into war Or use jetty Should be removed SpringBoot Built in tomcat package -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Add war package plug-in

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <!--If you want to web.xml Build with files WAR´╝îPlease set it to false. -->
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

Static file

In that project, add webapp directory to place static files, which will be automatically printed into war. It should be noted that creating web.xml under WEB-INF is an effective way to set filtering or sessionTime and other configurations in it.

3 reference link

1,https://baike.baidu.com/item/Spring%20Boot/20249767?fr=aladdin

2,https://www.zhihu.com/question/64671972/answer/223383505

3,https://blog.csdn.net/kikock/article/details/81021578

4,https://blog.csdn.net/d124939312/article/details/89711865

5,https://www.jianshu.com/p/2b14544f7773

6,https://www.jianshu.com/p/85d76c878fb0

7,https://nacos.io/zh-cn/docs/what-is-nacos.html

8,https://baijiahao.baidu.com/s?id=1634315317161175683&wfr=spider&for=pc

9,https://www.jianshu.com/p/d59f06724f1b

10,https://www.cnblogs.com/harrychinese/p/springboot_unittesting.html

Tags: Programming Spring Tomcat Maven xml

Posted on Tue, 04 Feb 2020 09:15:30 -0500 by Monk3h