SpringBoot starts its own homepage (in-depth discussion of configuration classes)–[CommandLineRunner]

SpringBoot series article directory

SpringBoot Knowledge Scope-Learning Steps – [Mind Map Knowledge Scope]

Article directory

  • SpringBoot series article directory
    • This series of school motto
  • There are many SpringBoot technologies
  • Environment and tools:
  • necessary knowledge
  • Common Configuration Classes
    • 1: Cross-domain request backend solution
    • 2: Encoding solves static files not loading
    • 3: MVC interceptor configuration
    • 4: upload path storage location
    • 5: Prevent SQL injection
    • 6: Automatic date in the database (creation date, modification date, etc.)
    • In addition: When encapsulating and returning the result set in a unified manner, solve the display of returning null values
  • code location.
  • Spring Boot startup class
  • supporting resources
  • Operation:

This series of school motto

Use the free public video to fly to the training class! If you are beaten to death, you will not report to work, and you will make money by working hard!
As long as you have a computer, you can do front and rear projects! N years of studying hard and no one asked, once you become famous, the world knows it!

There are many SpringBoot technologies

This article specifically discusses the use of CommandLineRunner, which must depend on org.springframework.boot, so the project must be a springBoot project

Han Shunping said: People who learn JAVA have two major difficulties
The first confusion is that JAVA can get too much knowledge from Baidu, and I don’t know what to learn at all.
The second confusion is that I don’t know in what order to learn. Sometimes there are omissions in a bunch of videos, and sometimes the videos on both sides are repeated.
It is suggested that after learning the technology on the right, you should invest in the learning of the project. It will be much better to learn the technology on the left in the project.
There are more peripheral technologies of Spring. This example is also a peripheral technology of springBoot, but it is not in the chart below.

Therefore, learning things should be more systematic. If the basic skills are not enough, then the subsequent techniques will be very easy to learn.

Environment and tools:

Environment of this series

environment win11
tools idea 2018
jdk 1.8
database This example is not Need
maven 3.2.1
Project import method Maven import
Database front-end tools This example does not need

Database front-end tool: mysql-front (navicat is also available)
The main reason is that these are integrated with PHPStudy 2018, so sometimes it is lazy to open navicat
Regarding the importance of the environment, directly read the above “SpringBoot project compilation and error handling – JSB series 001”

Necessary knowledge

configuration class
Let’s discuss configuration classes in depth here.

Multiple configuration classes need to be loaded when the project starts, and the loading order of certain configuration classes needs to be controlled. Use @Configuration to annotate configuration classes, and use @AutoConfigureAfter and @AutoConfigureBefore to set the loading order of configuration classes.
Result: The configuration class can be loaded normally, but the loading order of the configuration class cannot be controlled.

Several annotations @ComponentScan: Automatically scan components. value
Specify the scanned package path, and automatically assemble the classes (@Controller, @Service, @Repository, @Configuration, etc.) that need to be assembled under the package path into the Spring bean container.
When starting SpringBoot, if @ComponentScan is configured, the scanned package path is the configured package path; if @ComponentScan is not configured, the scanned package path defaults to the package path where the SpringBootApplication startup class is located.

@Configuration: Modifies the class, indicating that the current class is a configuration class. If the class is under the package path specified by @ComponentScan, then when SpringBoot is started, the class will be automatically assembled into the Spring Bean container.
@AutoConfigurationAfter: Indicates that the current configuration class is loaded after a certain configuration class is loaded.
@AutoConfigurationBefore: Indicates that the current configuration class is loaded before a certain configuration class is loaded.

Common configuration classes

1: Cross-domain request backend solution

package com.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//Solve cross-domain issues
@Configuration
public class CrosConfig implements WebMvcConfigurer {<!-- -->

    @Override
    public void addCorsMappings(CorsRegistry registry) {<!-- -->
        registry. addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET","POST","HEAD","PUT","DELETE")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }

// If the interceptor is configured at the same time, the above method will fail, and the following method can be used to solve the cross-domain problem
/**
     * Problem: When configuring JWT, cross-domain problems occur when using interceptors
     * across configuration
     * Use the filter CorsFilter to configure cross-domain. Since the position of the Filter is before the Interceptor, the problem is solved:
     */

    @Autowired
    JWTInterceptorjwtInterceptor;

    @Bean
    public CorsFilter corsFilter() {<!-- -->
        CorsConfiguration config = new CorsConfiguration();
        // Set the domain name that allows cross-domain requests
        config.addAllowedOrigin("*");
        // Whether to allow certificates is no longer enabled by default
         config.setAllowCredentials(true);
        // Set allowed methods
        config.addAllowedMethod("*");
        // allow any header
        config.addAllowedHeader("*");
        config.addExposedHeader("token");
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }
}

2: Encoding solves static files not loading

package com.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.interceptor.AuthorizationInterceptor;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{<!-- -->
\t
/**
* After springboot 2.0 configures WebMvcConfigurationSupport, the default configuration will be overwritten. To access static resources, you need to rewrite the addResourceHandlers method
*/
@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {<!-- -->
registry. addResourceHandler("/**")
        .addResourceLocations("classpath:/resources/")
        .addResourceLocations("classpath:/static/")
        .addResourceLocations("classpath:/admin/")
        .addResourceLocations("classpath:/front/")
        .addResourceLocations("classpath:/public/");
super. addResourceHandlers(registry);
    }
}

3: MVC interceptor configuration

It is mainly to prevent users from not logging in and to penetrate the URL behind (that is, to directly enter the URL to access the permission-controlled page behind)

package com.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.interceptor.AuthorizationInterceptor;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{<!-- -->
\t
@Bean
    public AuthorizationInterceptor getAuthorizationInterceptor() {<!-- -->
        return new AuthorizationInterceptor();
    }
\t
@Override
    public void addInterceptors(InterceptorRegistry registry) {<!-- -->
        registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
        super. addInterceptors(registry);
}
\t
/**
* After springboot 2.0 configures WebMvcConfigurationSupport, the default configuration will be overwritten. To access static resources, you need to rewrite the addResourceHandlers method
*/
@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {<!-- -->
registry. addResourceHandler("/**")
        .addResourceLocations("classpath:/resources/")
        .addResourceLocations("classpath:/static/")
        .addResourceLocations("classpath:/admin/")
        .addResourceLocations("classpath:/front/")
        .addResourceLocations("classpath:/public/");
super. addResourceHandlers(registry);
    }
}

4: upload path storage location

package com.spring.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfigure implements WebMvcConfigurer {<!-- -->

    /**
     * Set the storage location of the upload path, which is uploaded in the running directory by default
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {<!-- -->
        // set orientation address
        System.out.println(Configure.UPLOAD_DIR);
        registry
            .addResourceHandler("/upload/**")
            .addResourceLocations("file:" + Configure.UPLOAD_DIR)
            .addResourceLocations("file:" + System.getProperty("user.dir") + "/src/webapp/upload/");
    }
}

5: Prevent SQL injection

package com.spring.config;

import com.jntoo.db.Configuration;
import com.jntoo.db.QueryConfig;
import javax.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * Configure database access source
 */
@Component
public class QueryConfigRuntime implements ApplicationRunner {<!-- -->

    @Resource
    private QueryConfigConnect config;

    /**
     * Callback used to run the bean.
     *
     * @param args incoming application arguments
     * @throws Exception on error
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {<!-- -->
        QueryConfig queryConfig = new QueryConfig();
        queryConfig.setPrefix("");
        queryConfig.setConnectionConfig(config);
        queryConfig.setDebug(true);
        Configuration.setQueryConfig(queryConfig);
    }
}

6: Automatic date in the database (creation date, modification date, etc.)

Generated here in the background, it is more accurate than the front-end, and it is more portable than the database.
However, these fields are required to have consistent field names

package com.config;

import java.util.Date;

import org.apache.ibatis.reflection.MetaObject;

import com.baomidou.mybatisplus.mapper.MetaObjectHandler;

/**
 * Custom Fill Processor
 */
public class MyMetaObjectHandler extends MetaObjectHandler {<!-- -->

    @Override
    public void insertFill(MetaObject metaObject) {<!-- -->
        this.setFieldValByName("ctime", new Date(), metaObject);
    }

    @Override
    public boolean openUpdateFill() {<!-- -->
        return false;
    }

    @Override
    public void updateFill(MetaObject metaObject) {<!-- -->
        // Close the update fill, not executed here
    }
}

In addition: When encapsulating and returning the result set in a unified manner, the solution returns null value display

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;

/**
 * Use SpringBoot's default jackjson to solve the situation that the unified result set is empty
 * */


@Configuration
public class NullValueConfiguration {<!-- -->
    
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper. class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {<!-- -->
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {<!-- -->
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, IOException {<!-- -->
                jsonGenerator.writeString("");
            }
        });
        return objectMapper;
    }
}

This article is also a configuration class. Very practical. It’s easy to learn.
It’s just a project. After a period of time, I often can’t find the starting home page. Some items are not convenient to jump in index.html.

Then, the configuration class of this article can be launched.

public class AutoStartProjectInDefaultBrowser implements CommandLineRunner

It also takes the class in SpringBoot.
The overall code is as follows:

package com.config;

import java.lang.reflect.*;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringBootConfiguration;

/**
 * Execute here after the system starts, run the browser
 */
@SpringBootConfiguration
public class AutoStartProjectInDefaultBrowser implements CommandLineRunner {<!-- -->

    @Value("${server.port}")
    private String port;

    @Value("${server.servlet.context-path}")
    private String path;

   String home_path = "/front/pages/login/login.html";

    /**
     * The monitoring task that comes with springboot starts the browser
     *
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {<!-- -->
        try {<!-- -->
            String url = "http://localhost:" + port + path + home_path;
            browse(url);
            //Runtime.getRuntime().exec("cmd /c start http://localhost:" + port + "" + path);
        } catch (Exception ex) {<!-- -->
            ex. printStackTrace();
        }
    }

    private static void browse(String url) {<!-- -->
        try {<!-- -->
            String osName = System. getProperty("os. name", "");
            if (osName. startsWith("Mac OS")) {<!-- -->
                Class fileMgr = Class.forName("com.apple.eio.FileManager");
                Method openURL = fileMgr. getDeclaredMethod("openURL", String. class);
                openURL.invoke(null, url);
            } else if (osName. startsWith("Windows")) {<!-- -->
                Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
            } else {<!-- -->
                // Unix or Linux
                String[] browsers = {<!-- -->"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape"};
                String browser = null;
                for (int count = 0; count < browsers.length & amp; & amp; browser == null; count ++ ) // Execute the code and jump out after the browser has a value,
                    // Here is if the process is created successfully, ==0 means normal end.
                    if (Runtime.getRuntime().exec(new String[]{<!-- -->"which", browsers[count]}).waitFor() == 0)
                        browser = browsers[count];
                if (browser == null) throw new Exception("Could not find web browser");
                else // This value has been successfully obtained by a process above.
                    Runtime.getRuntime().exec(new String[]{<!-- -->browser, url});
            }
        } catch (Exception e) {<!-- -->
            e.printStackTrace();
        }
    }
}

That’s it.

code location.

Spring Boot startup class

Record the startup user and password in the startup class

package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
@MapperScan(basePackages = {<!-- -->"com.dao"})
public class SpringbootSchemaApplication extends SpringBootServletInitializer{<!-- -->

public static void main(String[] args) {<!-- -->
SpringApplication.run(SpringbootSchemaApplication.class, args);
System.out.println("Click the following link to visit the home page:");
System.out.println("http://localhost:8080/springbootj470j/front/pages/login/login.html");
System.out.println("Foreground user password: 11/11");
System.out.println("background user password: admin/admin");

}
\t
@Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder) {<!-- -->
        return applicationBuilder.sources(SpringbootSchemaApplication.class);
        //http://localhost:8080/springbootj470j/front/pages/login/login.html

    }
}

The final result.

in addition:
You can also record other configuration requirements of the project in the startup class:
The name of the datasource in the datasource. Username Password. Also, the mysql driver is com.mysql.jdbc.Driver
In general,
com.mysql.jdbc.Driver is before mysql-connector-java 5.5,
com.mysql.cj.jdbc.Driver is mysql-connector-java 6 and later,
Beginners tend to fall into a misunderstanding, that is, the latest version of something is the best. In fact, it is very likely that what he wrote is obviously enough for JDK6.0. While shouting that his machine has insufficient memory, he let the memory run things that he can’t use. For example, idea should be regarded as the most stuck among these developer tools. Someone might just open a few web pages, so why not use webstorm? Even when writing a lot of code, why not choose the lighter-weight VSCode?

Supporting resources

supporting resources
none

Assignment:

No, understanding is God
Learn SpringBoot, there are many things in it, no one can touch it before work, the accumulation of experience is the key to smooth promotion at work