SpringBoot Web development and source code analysis

SpringBoot quick start

For conceptual things, see: https://www.yuque.com/atguigu/springboot/rmxq85

Required environment: jdk8 & compatible with java14, maven 3.3+, idea 219.1.2

maven settings:

Go to maven's configuration file to modify and add:

        <name>Nexus aliyun</name>

Step 1: create maven project

Step 2: import dependency in pom file:




step 3: create package and main class (also called main application) under src/main/java

// Tell springboot that this is a springboot application
// Main program application
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);

step 4: create a Controller under another package and write business code

You can use RestController instead
@ResponseBody // Represents that this class returns a string
public class HelloController {
    public String handle01() {
        return "hello SpringBoot";

step 5: main method for directly running the main application

step 6: create an application.properties file under resource, which can be configured globally. See the official document for details

step 7: simplify deployment

By adding a plug-in, you can generate a jar package and execute it directly on the target server
(command line input: such as java -jar springboot01-1.0-SNAPSHOT.jar) note to cancel the Quick Edit mode of cmd


Under target /, SpringBoot packages us into a jar package, which contains the third-party jar package we need for runtime

SpringBoot auto configuration principle

1.0 basic features of springboot

1.1 dependency management

Dependency management    
Its parent project
It declares the version number of almost all dependencies commonly used in development,Automatic version arbitration mechanism, So we don't need to declare the version number

1. By default, no version can be written when importing dependencies
2. To import jar s that are not version arbitrated, write the version number.

Custom modification version number

1,see spring-boot-dependencies It specifies the current dependent version
2,Rewrite the configuration in the current project


A set of dependency descriptions is maven's dependency feature

1,See a lot spring-boot-starter-* :  *It's some kind of scene
2,Just introduce starter,We will automatically introduce all the dependencies required for this scenario
3,SpringBoot All supported scenarios
4,See  *-spring-boot-starter:  Scenario launcher for simplified development provided by the third party
5,The lowest level dependency of all scenario initiators:

1.2 automatic configuration

  • Automatically configure Tomcat

    • Introduce dependency
    • Configure Tomcat
  • Automatically configure spring MVC

    • The full set of components of spring MVC is introduced
      How to view the components of the IOC container:

      Main method under main program application:
      public static void main(String[] args) {
              // Return to IOC container
              ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
              // View container component name
              String[] names = run.getBeanDefinitionNames();
              for(String s : names) {
          	run.getBean("yang", User.class); // There is only one single instance of a component in the container
    • Spring MVC common components (functions) are automatically configured

  • Automatically configure common Web functions, such as character encoding

  • Default package structure

    • All components of the package where the main program is located and its sub packages will be scanned by default
    • No previous package scan configuration is required
    • To change the scanning path, @ SpringBootApplication(scanBasePackages = "com.yangyu")
      Or @ ComponentScan specifies the scan path
 Equivalent to
@ComponentScan("com.atguigu.boot") // The scan path can be specified here
  • Various configurations have default values
    • The default configuration is ultimately mapped to a class, such as MultipartProperties
    • The value of the configuration file will eventually be bound to each class, which will create objects in the container
  • Load all auto configuration items on demand
    • Very many starter s
    • As long as this scenario is introduced, the automatic configuration of this scenario will be enabled
    • All spring boot autoconfigure functions are in the spring boot autoconfigure package

2.0 container function

2.1 component addition

1. @Configuration

Spring adds components by creating classes, creating spring configuration files, and writing < beans > in xml files

How to add components to SpringBoot:

  • There is no dependency between configuration class components. Use Lite mode to accelerate the container startup process and reduce judgment

  • There are dependencies between configuration class components, and the method will be called to obtain the previous single instance component in Full mode

1. @Bean Is to register components for containers. The default is single instance
2. The configuration class itself is also a component
3. proxyBeanMethods: The method of the code bean defaults to true  
	Full(proxyBeanMethods = true) (Ensure that each @ Bean method is called many times, and the returned component is single instance) 
	Lite(proxyBeanMethods = false) (How many times each @ Bean method is called, the returned component is newly created, and the container does not save the proxy object)
    Component dependencies must use the Full mode default. The other defaults to Lite mode
@Configuration(proxyBeanMethods = true) // Tell SpringBoot that this is the default single instance of a configuration class
public class MyConfig {

    // Full: no matter how many external calls are made to this component registration method in the configuration class, the single instance object in the previous registration container is obtained
    @Bean // Add a component to the container, take the method name as the component id, the return type is the component type, and the returned value is the instance of the component in the container
    public User user01() {
        return new User("01", 20);
    public User yangyu() {
        return new User("yangyu", 20);

2. @Component @Controller @Service @Repository (applicable to labeling self written classes) @ Bean (applicable to labeling components in third-party packages)

3. @ComponentScan @Import (quickly import components into the container)

@Import({User.class, DBHelper.class})
Automatically create these two types of components in the container. The name of the default component is the full class name

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false)
public class MyConfig {

ImportSelector: it is an interface that needs to be implemented by a custom class. The method that needs to be rewritten can return the full class name array of the components to be imported. The full class name of the class that needs to be returned can be obtained through its own logic, and then a full class name string group is returned. Note: in the config class, you need to @ import the class of the interface you implement, In this way, the corresponding instance will be automatically generated in the container. The class of the interface you implement will not generate an instance in the container

ImportBeanDefinitionRegistrar: it is also an interface that needs to be implemented. Call BeanDefinitionRegistry.registerBeanDefinition to manually register all beans that need to be added to the container

**Factorbean (provided by spring): * * is also an interface and needs to be implemented

4. @Conditional

Conditional assembly: component injection is performed when the specified conditions are met

ConditionOnBean: only when there is this component in the container

@ConditionalOnBean(name = {"user01", "myConfig"})

2.2 native configuration file import

1. @ImportResource

Native XML: Resources / beans.xml

public class MyConfig {}

2.3 configuration binding

Read the contents of the properties file and package it into JavaBean s for use at any time;

Native java practices:

public class getProperties {
     public static void main(String[] args) throws FileNotFoundException, IOException {
         Properties pps = new Properties();
         pps.load(new FileInputStream("a.properties"));
         Enumeration enum1 = pps.propertyNames();//Get the name of the configuration file
         while(enum1.hasMoreElements()) {
             String strKey = (String) enum1.nextElement();
             String strValue = pps.getProperty(strKey);
             System.out.println(strKey + "=" + strValue);
             //Encapsulate into JavaBean s.

1. @ConfigurationProperties



Car class:

@Component // Only the components in the container have the powerful functions provided by SpringBoot
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private Integer aaa;
    private String bbb;

**2. @EnableConfigurationProperties + @ConfigurationProperties **

If it is a third-party class, use @ EnableConfigurationProperties(Car.class) on the configuration class

  1. Enable Car configuration binding
  2. Automatically register the Car component into the container

It is different from the previous one: either add it to the container with @ Component or use @ EnableConfigurationProperties

3.0 introduction to automatic configuration principle

3.1 boot load auto configuration class

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{}

1. @SpringBootConfiguration
Where @ Configuration represents the current class and is a Configuration class

2. @Component
Specify which packages to scan. Refer to the Spring annotation

3. EnableAutoConfiguration

public @interface EnableAutoConfiguration {}
  1. @AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class)  // Import a component into the container
public @interface AutoConfigurationPackage {}
// Use the Registrar to import a series of components into the container
// Import all components under the specified package: under the package of MainApplication
  1. @Import({AutoConfigurationImportSelector.class})
1,utilize getAutoConfigurationEntry(annotationMetadata);Batch import some components into the container
2,call List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)Get all the configuration classes that need to be imported into the container
3,Using factory loading Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) Get all the components
4,from META-INF/spring.factories Location to load a file.
By default, it scans all of our current systems META-INF/spring.factories Location file
spring-boot-autoconfigure-2.3.4.RELEASE.jar It's also in the bag META-INF/spring.factories
 It's dead in the file spring-boot All configuration classes loaded in the container should be given as soon as they are started

3.2 turn on automatic configuration items on demand

Although all the automatic configurations of our 127 scenarios are loaded by default when they are started. xxxxAutoConfiguration
According to the Conditional assembly rule (@ Conditional), it will be configured as required.

3.3 source code analysis and modification of default configuration

@ConditionalOnBean(MultipartResolver.class)  // There are components of this type in the container
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) // There is no component with this name multipartResolver in the container
public MultipartResolver multipartResolver(MultipartResolver resolver) {
	// If the method labeled @ Bean passes in an object parameter, the value of this parameter will be found from the container.
	// SpringMVC multipartResolver.  Prevent the file upload parser configured by some users from not conforming to the specification
	// Detect if the user has created a MultipartResolver but named it incorrectly
	return resolver;
Add a file upload parser to the container;

SpringBoot will configure all components at the bottom by default. However, if the user has configured it himself, the user's priority shall prevail

public CharacterEncodingFilter characterEncodingFilter() {}

If you want to match yourself:
public CharacterEncodingFilter filter(){
    return null;


  • SpringBoot loads all the autoconfiguration classes xxxxconfiguration first

  • Each automatic configuration class takes effect according to conditions, and will bind the value specified in the configuration file by default. The. xxxProperties are bound to the configuration file in xxxProperties

  • The effective configuration class will assemble many components in the container

  • As long as these components are in the container, they are equivalent to these functions

  • Customized configuration

    • Users directly replace the underlying components with @ Bean
    • The user can modify the value of the configuration file obtained by this component.

Xxxxxxautoconfiguration - > component - > xxxxproperties - > get the value - > application.properties

3.4 best practices

  • Introduce scenario dependency
  • View what you have configured (optional)
    • Analyze the source code and introduce the automatic configuration of the scene, which generally takes effect
    • Enter debug=true in application.properties to enable the automatic configuration report Negative matches \ Positive matches
  • Need to modify
    • Modify configuration items by referencing documents
      Analyze for yourself: which of the configuration files are bound by xxproperties
    • Custom add or replace components
      @Bean @Component
    • Customizer XXXCustomizer
Development skills

Simplify JavaBean development

And in idea Search installation lombok plug-in unit
// Simplified log development
public class HelloController {
    public String handle01(){
        log.info("The request came in....");
        return "123"

Hot update (actually automatic restart)


After modifying the item or page: Ctrl+F9

Spring Initailizr

IDEA can quickly create SpringBoot applications, check the scenes you need, and automatically generate pom files

4.0 configuration file

4.1 properties

4.2 yaml

It is still a markup language

It is very suitable for data centric configuration files

Basic syntax:

  • key: value; There is a space between K and V

  • Case sensitive

  • Use indentation to represent hierarchical relationships

  • tab is not allowed for indentation, only spaces are allowed

  • The number of indented spaces is not important, as long as the elements of the same level are aligned to the left

  • '#' indicates a comment

  • There is no need to quote the string. If you want to add, '' and '' means that the string content will be escaped / not escaped

Data type:

  • Literal: a single, non separable value. date,boolean,string,number,null

    k: v
  • Object: a collection of key value pairs. map,hash,set,object

    Inline writing:  k: {k1:v1,k2:v2,k3:v3} #No spaces
      k1: v1
      k2: v2
      k3: v3
  • Array: a set of values arranged in order: array, list, queue

    Inline writing:  k: [v1,v2,v3]
     - v1
     - v2
     - v3


# yaml represents the above objects
  userName: zhangsan
  boss: false
  birth: 2019/12/12 20:12:33 # private Date birth;
  age: 18
  pet: # private Pet pet
    name: tomcat
    weight: 23.4
  interests: [Basketball,Swimming] # private String[] interests;
  animal:   # private List<String> animal;
    - jerry
    - mario
  score: # private Map<String, Object> score;
      first: 30
      second: 40
      third: 50
    math: [131,140,148]
    chinese: {first: 128,second: 136}
  salarys: # private Set<Double> salarys;
    - 9999.98
    - 9999.99 
  allPets: # private Map<String, List<Pet>> allPets;
      - {name: tom}
      - {name: jerry,weight: 47}
      - name: A bug
        weight: 77.77
    health: [{name: mario,weight: 47}]

4.3 configuration tips

Custom class and configuration file binding are generally not prompted


<!-- Prevent typing in when packing --> 

Web development

1.0 spring MVC auto configuration overview

Spring boot provides auto configuration for spring MVC that works well with most applications

The auto-configuration adds the following features on top of Spring's defaults:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
    • Content negotiation view parser and BeanName view parser
  • Support for serving static resources, including support for WebJars (covered later in this document)).
    • Static resources (including webjars)
  • Automatic registration of Converter, GenericConverter, and Formatter beans.
    • Automatically register Converter, GenericConverter, Formatter
  • Support for HttpMessageConverters (covered later in this document).
    • Support HttpMessageConverters (later we cooperated with content negotiation to understand the principle)
  • Automatic registration of MessageCodesResolver (covered later in this document).
    • Automatically register MessageCodesResolver (for internationalization)
    • Static index.html support.
    • Static index.html page support
  • Custom Favicon support (covered later in this document).
    • Custom Favicon
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
    • Automatically use the configurablewebbindinginitializer (databinder is responsible for binding the request data to the JavaBean)

If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

Do not use @ EnableWebMvc annotation. Use @ Configuration + WebMvcConfigurer to customize rules

If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

Declaring WebMvcRegistrations changes the default underlying components

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

Use @ EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration to fully take over spring MVC

2.0 simple function analysis

2.1 static resource access

As long as static resources are placed in the classpath: / static or /public or /resources or /META-INF/resources

Access: current project root path / + static resource name

Principle: static mapping/**

When the request comes in, first go to the Controller to see if it can be processed. All requests that cannot be processed are handed over to the static resource processor. If the static resource cannot be found, respond to page 404

Change the default static resource address

    static-path-pattern: /res/**
    static-locations: [classpath:/haha/]

spring.resources.static-locations is used to tell Spring Boot where to find static resource files. This is a list configuration. When finding files, it depends on the order of configuration. The default official configuration is as follows:

In order to prevent static resources from being intercepted by the interceptor in actual development, a prefix will be added to the static resource path to allow the interceptor to release all requests for the path with the specified prefix

Current project + static path pattern + static resource name = static resource folder


Automatic mapping/ webjars/**


Access address: http://localhost:8080/webjars/jquery/3.5.1/jquery.js The following address depends on the package path inside

2.2 welcome page support

  • index.html under static resource path
    • Static resource paths can be configured
    • However, the access prefix of static resources cannot be configured, otherwise index.html cannot be accessed by default
    • controller can handle / index
  • spring:
    #  mvc:
    #    Static path pattern: / RES / * * this will cause the function of the welcome page to fail
        static-locations: [classpath:/haha/]

2.3 custom Favicon

favicon.ico can be placed in the static resource directory, and static path pattern: / RES / * * will cause the function of the welcome page to fail

2.4 static resource allocation principle

  • SpringBoot starts by loading the xxxAutoConfiguration class (autoconfiguration class) by default

  • The automatic configuration class webmvcoautoconfiguration of spring MVC function takes effect

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnWebApplication(type = Type.SERVLET)
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
    		ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration {}
  • The relevant properties of the configuration file are bound to xxx. WebMvcProperties==spring.mvc ResourceProperties==spring.resources

            proxyBeanMethods = false
    @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})

    1. There is only one constructor with parameters

    // The values of all parameters of the parameterized constructor are determined from the container
    // ResourceProperties resourceProperties; an object that gets all values bound to spring.resources
    // WebMvcProperties mvcProperties object that gets all values bound to spring.mvc
    // Listablebeanfactory beanFactory beanfactory of spring
    // HttpMessageConverters find all HttpMessageConverters
    // ResourceHandlerRegistrationCustomizer found the customizer for the resource processor=========
    // DispatcherServletPath  
    // The ServletRegistrationBean registers servlets, filters
    public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
    	ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
    	ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
    	ObjectProvider<DispatcherServletPath> dispatcherServletPath,
    	ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
    		this.resourceProperties = resourceProperties;
    		this.mvcProperties = mvcProperties;
    		this.beanFactory = beanFactory;
    		this.messageConvertersProvider = messageConvertersProvider;
    		this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
    		this.dispatcherServletPath = dispatcherServletPath;
    		this.servletRegistrations = servletRegistrations;

    2. Default rules for resource processing

    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    	if (!this.resourceProperties.isAddMappings()) {
    		logger.debug("Default resource handling disabled");
    	addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    	addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
    		if (this.servletContext != null) {
    			ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
    #  mvc:
    #    static-path-pattern: /res/**
        add-mappings: false   Disable all static resource rules
    public static class Resources {
    	private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
    				"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
        * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
        * /resources/, /static/, /public/].
    	private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

    3. Welcome page processing rules
    Under EnableWebMvcConfiguration class

    HandlerMapping: Processor mapping. Saved each Handler Which requests can be processed.
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
    	FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    		WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
    				new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
    		welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    		return welcomePageHandlerMapping;
    // The welcome page function is dead
    WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
    			ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
         //To use the welcome page function, you must be/**
    	if (welcomePage != null && "/**".equals(staticPathPattern)) {
    		logger.info("Adding welcome page: " + welcomePage);
    	else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
            // Call controller / index
    		logger.info("Adding welcome page template: index");

3.0 request parameter processing

3.1 request mapping

  • xxxMapping

  • Rest style support (use HTTP request mode verbs to indicate the operation of resources)

    • Previous: / getUser get user / deleteUser delete user / editUser modify user / saveUser save user

    • Now: / user GET - get user DELETE - DELETE user PUT - modify user POST - save user

    • Core Filter; HiddenHttpMethodFilter

      • Usage: form method=post, hide field_ method=put

      • Manual startup in SpringBoot

              enable: true
    • Extension: how to_ Change the name method to our own favorite.

// Test code
//@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getUser(){
    return "GET-Zhang San";

//@RequestMapping(value = "/user",method = RequestMethod.POST)
public String saveUser(){
    return "POST-Zhang San";

//@RequestMapping(value = "/user",method = RequestMethod.PUT)
public String putUser(){
    return "PUT-Zhang San";

//@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
    return "DELETE-Zhang San";

@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
	return new OrderedHiddenHttpMethodFilter();

//Create a configuration class and customize the filter in the class
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
	HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
    return methodFilter;

REST principle (when REST is used for form submission)

  • The form will be submitted with_ method=PUT
  • The request was intercepted by HiddenHttpMethodFilter
    • Is the request normal and POST
      • Get**_ method * *.
      • Compatible with the following requests; PUT.DELETE.PATCH
      • Native request (post). The wrapper pattern requestwrapper overrides the getMethod method method and returns the passed in value
      • When the filter chain is released, use wrapper. The later method to call getMethod is the getMethod to call requestwrapper

Rest uses client tools,

  • For example, PostMan directly sends Put, delete and other requests without Filter

3.2 request mapping principle

Observe the inheritance tree of the dispatcher servlet
Spring MVC functional analysis starts with doDispatch() of org.springframework.web.servlet.DispatcherServlet

// Find which Handler (Controller's method) is used to process the current request
mappedHandler = getHandler(processedRequest);
// Handler mapping: processor mapping/ xxx -> xxxx

RequestMapping handler mapping: saves the mapping rules of all @ RequestMapping and handlers

All request mappings are in HandlerMapping

  • SpringBoot automatically configures the welcome pagehandlermapping of the welcome page. You can access / access index.html;

  • SpringBoot automatically configures the default RequestMappingHandlerMapping

  • Request to come in and try all HandlerMapping one by one to see if there is the requested information

    • If yes, find the handler corresponding to the request
    • If not, find the next HandlerMapping
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    if (this.handlerMappings != null) {
        for (HandlerMapping mapping : this.handlerMappings) {
            HandlerExecutionChain handler = mapping.getHandler(request);
            if (handler != null) {
                return handler;
    return null;
  • We need some custom mapping processing. We can also put HandlerMapping. Custom HandlerMapping in the container ourselves

3.3 general parameters and basic notes

1. Notes

@PathVariable, @RequestParam, @RequestBody, @CookieValue, @RequestHeader :

 //  car/2/owner/zhangsan path variable
    public Map<String,Object> getCar(@PathVariable("id") Integer id,
                                     @PathVariable("username") String name,
                                     @PathVariable Map<String,String> pv,
                                     @RequestHeader("User-Agent") String userAgent,
                                     @RequestHeader Map<String,String> header,
                                     @RequestParam("age") Integer age,
                                     @RequestParam("inters") List<String> inters,
                                     @RequestParam Map<String,String> params,
                                     @CookieValue("_ga") String _ga,
                                     @CookieValue("_ga") Cookie cookie){
        Map<String,Object> map = new HashMap<>();
//        map.put("id",id);
//        map.put("name",name);
//        map.put("pv",pv);
//        map.put("userAgent",userAgent);
//        map.put("headers",header);
        // inters is a linked list, so only one data is obtained
        return map;
    public Map postMethod(@RequestBody String content){
        Map<String,Object> map = new HashMap<>();
        return map;


    public String goToPage(HttpServletRequest request){
        return "forward:/success";  //Forward to / success request
    public String testParam(Map<String,Object> map,
                            Model model,
                            HttpServletRequest request,
                            HttpServletResponse response){

        Cookie cookie = new Cookie("c1","v1");
        return "forward:/success";
    public Map success(@RequestAttribute(value = "msg",required = false) String msg,
                       @RequestAttribute(value = "code",required = false)Integer code,
                       HttpServletRequest request){
        Object msg1 = request.getAttribute("msg");

        Map<String,Object> map = new HashMap<>();
        Object hello = request.getAttribute("hello");
        Object world = request.getAttribute("world");
        Object message = request.getAttribute("message");
        return map;

@MatrixVariable and UrlPathHelper
/cars/{path}? XXX = XXX & AAA = CCC querystring query string@ RequestParam;
/cars/sell;low=34;brand=byd,audi,yd ; Matrix variable

In page development, if cookie s are disabled, how to use the contents in the session
First, we can save data in the session, and everyone has a jssessionid. This jssessionid will be saved in the cookie, and the cookie will be carried every request, so the server will find it through the jssessionid of the cookie
We can solve this problem through matrix variables: url Rewriting: / ABC; Jssessionid = XXX passes the value of the cookie in the form of a matrix variable

The first semicolon is preceded by a path, followed by a matrix variable. Multiple matrix variables are distinguished by semicolons

//1. Syntax: request path: / cars/sell;low=34;brand=byd,audi,yd
//2. SpringBoot disables the function of matrix variables by default
//              Manual opening: Principle: for path processing: the UrlPathHelper parses. The removeSemicolonContent (remove semicolon content) is used to support the processing of matrix variables
//3. The matrix variable must have a url path variable to be resolved
    public Map carsSell(@MatrixVariable("low") Integer low,
                        @MatrixVariable("brand") List<String> brand,
                        @PathVariable("path") String path){
        Map<String,Object> map = new HashMap<>();
        return map;
    // /boss/1;age=20/2;age=10
    public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
                    @MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
        Map<String,Object> map = new HashMap<>();
        return map;

Manually turn on the matrix variable:

@Configuration(proxyBeanMethods = false)
public class WebConfig /*implements WebMvcConfigurer*/ {
    //1. WebMvcConfigurer customizes the functionality of spring MVC
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                // Not removed; What follows. The matrix variable function can take effect

2. Servlet API

WebRequest,ServletRequest,MultipartRequest, HttpSession,javax.servlet.http.PushBuilder,Principal,InputStream,Reader,HttpMethod,Locale,TimeZone,ZoneId

ServletRequestMethodArgumentResolver can resolve some of the above parameters

public boolean supportsParameter(MethodParameter parameter) {
    Class<?> paramType = parameter.getParameterType();
    return (WebRequest.class.isAssignableFrom(paramType) ||
            ServletRequest.class.isAssignableFrom(paramType) ||
            MultipartRequest.class.isAssignableFrom(paramType) ||
            HttpSession.class.isAssignableFrom(paramType) ||
            (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
            Principal.class.isAssignableFrom(paramType) ||
            InputStream.class.isAssignableFrom(paramType) ||
            Reader.class.isAssignableFrom(paramType) ||
            HttpMethod.class == paramType ||
            Locale.class == paramType ||
            TimeZone.class == paramType ||
            ZoneId.class == paramType);

3. Complex parameters

Map, * * model (the data in map and model will be placed in the request field of request request.setAttribute), * * Errors/BindingResult, RedirectAttributes (redirect carried data), ServletResponse (response), SessionStatus, UriComponentsBuilder, ServletUriComponentsBuilder

Map<String,Object> map,  Model model, HttpServletRequest request All can be given request Put data in the domain,

Map, a parameter of Model type, will return mavContainer.getModel(); (BindingAwareModelMap type, which is both Model and Map)

Model stores data and View stores View

4. User defined object parameters

Automatic type conversion and formatting, cascading encapsulation

 *     Name: < input name = "username" / > < br / >
 *     Age: < input name = "age" / > < br / >
 *     Birthday: < input name = "birth" / > < br / >
 *     Pet name: < input name = "pet. Name" / > < br / >
 *     Pet age: < input name = "pet. Age" / >
public class Person {
    private String userName;
    private Integer age;
    private Date birth;
    private Pet pet;
public class Pet {
    private String name;
    private String age;

5. POJO packaging process

The parameter processing of ServletModelAttributeMethodProcessor is shown below

3.4 parameter processing principle

  • The Handler (Controller.method()) that can handle the request is found in the HandlerMapping

  • Find an adapter HandlerAdapter for the current Handler; RequestMappingHandlerAdapter

  • The adapter executes the target method and determines each value of the method parameter

1. HandlerAdapter

0 - support annotation @ RequestMapping on method
1 - support for functional programming

2. Implementation objectives and methods

// Actually invoke the handler.
// doDispatch method in DispatcherServlet class
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
mav = invokeHandlerMethod(request, response, handlerMethod); // Execution target method
// ServletInvocableHandlerMethod actually executes the target method
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
// Gets the parameter value of the method
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);

3. Parameter resolver - HandlerMethodArgumentResolver

Determine the value of each parameter of the target method to be executed

How many parameter types the spring MVC target method can write depends on the parameter parser

Parameter parser interface:

  • Does the current parser support parsing such parameters
  • It supports calling resolveArgument (return value processor) on

4. Return value processor

5. Determine the value of each parameter of the target method

protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
		MethodParameter[] parameters = getMethodParameters();
		if (ObjectUtils.isEmpty(parameters)) {
			return EMPTY_ARGS;
		Object[] args = new Object[parameters.length];
		for (int i = 0; i < parameters.length; i++) {
			MethodParameter parameter = parameters[i];
			args[i] = findProvidedArgument(parameter, providedArgs);
			if (args[i] != null) {
			if (!this.resolvers.supportsParameter(parameter)) {
				throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
			try {
				args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
			catch (Exception ex) {
				// Leave stack trace for later, exception may actually be resolved and handled...
				if (logger.isDebugEnabled()) {
					String exMsg = ex.getMessage();
					if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
						logger.debug(formatArgumentError(parameter, exMsg));
				throw ex;
		return args;

6. Traverse to find which parameter parser can support parsing this parameter

private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
    HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
    if (result == null) {
      for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
        if (resolver.supportsParameter(parameter)) {
          result = resolver;
          this.argumentResolverCache.put(parameter, result);
    return result;

7. Parse the value of this parameter

Call the resolveArgument method of the respective HandlerMethodArgumentResolver

8. User defined type parameter encapsulation POJO

ServletModelAttributeMethodProcessor this parameter is supported by the parser
Simple type:

public static boolean isSimpleValueType(Class<?> type) {
		return (Void.class != type && void.class != type &&
				(ClassUtils.isPrimitiveOrWrapper(type) ||
				Enum.class.isAssignableFrom(type) ||
				CharSequence.class.isAssignableFrom(type) ||
				Number.class.isAssignableFrom(type) ||
				Date.class.isAssignableFrom(type) ||
				Temporal.class.isAssignableFrom(type) ||
				URI.class == type ||
				URL.class == type ||
				Locale.class == type ||
				Class.class == type));

WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
Webdatabinder: a web data binder that binds the value of the request parameter to the specified JavaBean
WebDataBinder uses its Converters to convert the requested data into the specified data type. It is encapsulated into a JavaBean again

GenericConversionService: when setting each value, find all converter s in it, which can convert this data type (string with parameter brought by request) to the specified type (JavaBean – Integer)
For example: file upload: byte – > file

@FunctionalInterface public interface Converter<S, T>

In the future, we can put our own Converter in WebDataBinder;

private static final class StringToNumber<T extends Number> implements Converter<String, T>

Custom Converter:

    //1. WebMvcConfigurer customizes the functionality of spring MVC
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                // Not removed; What follows. The matrix variable function can take effect
            public void addFormatters(FormatterRegistry registry) {
                registry.addConverter(new Converter<String, Pet>() {
                    public Pet convert(String source) {
                        // Ah, cat, 3
                            Pet pet = new Pet();
                            String[] split = source.split(",");
                            return pet;
                        return null;

3.5 completion of target method implementation

Put all data in ModelAndViewContainer; Contains the page address to go. View. Also contains Model data

3.5.1 processing and distribution results

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);

	protected void renderMergedOutputModel(
			Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

		// Expose the model object as request attributes.
		exposeModelAsRequestAttributes(model, request);

		// Expose helpers as request attributes, if any.

		// Determine the path for the request dispatcher.
		String dispatcherPath = prepareForRendering(request, response);

		// Obtain a RequestDispatcher for the target resource (typically a JSP).
		RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
		if (rd == null) {
			throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
					"]: Check that the corresponding file exists within your web application archive!");

		// If already included or response already committed, perform include, else forward.
		if (useInclude(request, response)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Including [" + getUrl() + "]");
			rd.include(request, response);

		else {
			// Note: The forwarded resource is supposed to determine the content type itself.
			if (logger.isDebugEnabled()) {
				logger.debug("Forwarding to [" + getUrl() + "]");
			rd.forward(request, response);

Expose the model as a request domain attribute / / Expose the model object as request attributes

exposeModelAsRequestAttributes(model, request);

protected void exposeModelAsRequestAttributes(Map<String, Object> model,
			HttpServletRequest request) throws Exception {
        // All data traversal in the model is placed in the request field one by one
		model.forEach((name, value) -> {
			if (value != null) {
				request.setAttribute(name, value);
			else {

4.0 data response and content negotiation

Data response

  • Response page
  • Response data
    • JSON
    • XML
    • xls
    • Pictures, audio and video
    • Custom protocol data

4.1 response JSON

1. jackson.jar + @ResponseBody


web scenarios automatically introduce json scenarios

Return value parser

try {
	returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
                              ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
    // Decide by this method
    HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
    if (handler == null) {
        throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
    handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
================= RequestResponseBodyMethodProcessor class==============
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
    throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
    ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
    ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
    // Try even with null return value. ResponseBodyAdvice could get involved.
    // Write out using message converters
    writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);

Return value parser principle

  • The return value processor determines whether this type of return value supportsreturnantype is supported
  • The return value handler calls handleReturnValue for processing
  • RequestResponseBodyMethodProcessor can process the returned value marked with @ ResponseBody annotation
    • Use MessageConverters to process and write the data as json
      • Content negotiation (by default, the browser will tell the server what content type it can accept in the form of request header)
      • The server finally determines what kind of content type data the server can produce according to its own ability,
      • Spring MVC will traverse the HttpMessageConverter at the bottom of all containers one by one to see who can handle it
        • Get MappingJackson2HttpMessageConverter and write the object as json
        • Use MappingJackson2HttpMessageConverter to convert the object into json and write it out

The return values that spring MVC supports are determined by returnValueHandlers

 yes @ModelAttribute And is of object type
@ResponseBody annotation ---> RequestResponseBodyMethodProcessor;

Principle of HTTPMessageConverter

  1. MessageConverter specification
    HttpMessageConverter: see whether it supports converting objects of this Class type into data of MediaType type

    For example, the Person object is converted to JSON or JSON is converted to Person

  2. Default MessageConverter

0 - only Byte type
1 - String
2 - String
3 - Resource
4 - ResourceRegion
5 - DOMSource.class \ SAXSource.class) \ StAXSource.class \ StreamSource.class \ Source.class
6 - MultiValueMap
7 - true
8 - true
9 - supporting xml processing in annotation mode

Finally, the MappingJackson2HttpMessageConverter converts the object into JSON (converted by the object mapper of the underlying jackson)

4.2 content negotiation

Data of different media types are returned according to different receiving capabilities of the client

1. Introduce xml dependency


2. The postman test returns json and xml
You only need to change the Accept field in the request header. As specified in the Http protocol, tell the server the data type that the client can receive: application/xml

3. Enable the browser parameter mode negotiation function

      favor-parameter: true  #Enable request parameter content negotiation mode



Determine what content type the client receives;

  1. The Parameter policy preferentially determines whether to return json data (get the value of format in the request header)
  2. Finally, negotiate the content and return it to the client json.

Content negotiation principle

  • 1. Judge whether there is a determined media type in the current response header. MediaType
  • 2. Get the content type supported by the client (PostMan, browser) (get the client Accept request header field) [application/xml]
    • The content negotiation manager uses the request header based policy by default
    • HeaderContentNegotiationStrategy() determines the type of content that the client can receive
  • 3. Cycle through all the messageconverters of the current system to see who supports the operation of this object (Person)
  • 4. Find the converter that supports the operation Person and count the media types supported by the converter
  • 5. The client needs [application/xml]. The server needs [10 kinds, json, xml]
  • 6. Best matching media type for content negotiation
  • 7. Use a converter that supports converting objects to best match media types. Call it for conversion

4.3 custom MessageConverter

Realize multi protocol data compatibility. json,xml,x-guigu

  1. @The ResponseBody response data goes out and calls the RequestResponseBodyMethodProcessor for processing

  2. The return value of the Processor processing method. Processing via MessageConverter

  3. All messageconverters together can support data operations (read and write) of various media types

  4. Find the final messageConverter through content negotiation;

What is the function of spring MVC. Add a WebMvcConfigurer to the container with an entry

public WebMvcConfigurer webMvcConfigurer(){
    return new WebMvcConfigurer() {

        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.add(new GuiguMessageConverter());
============ GuiguMessageConverter ============
public class GuiguMessageConverter implements HttpMessageConverter<Person> {
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return false;
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return clazz.isAssignableFrom(Person.class);
     * The server needs to count what content types can be written out by all messageconverters
     * application/x-guigu
     * @return
    public List<MediaType> getSupportedMediaTypes() {
        return MediaType.parseMediaTypes("application/x-guigu");
    public Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        //Writing out custom protocol data
        String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth();
        //Write it out
        OutputStream body = outputMessage.getBody();
================== WebConfig =================
      * Custom content negotiation policy
      * @param configurer
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    //Map<String, MediaType> mediaTypes
    Map<String, MediaType> mediaTypes = new HashMap<>();
    //Specify which media types correspond to which parameters support resolution
    ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);
    // parameterStrategy.setParameterName("gg");
    HeaderContentNegotiationStrategy headeStrategy = new HeaderContentNegotiationStrategy();

It is possible that the custom functions we added will override many default functions, resulting in some default functions invalid.

Let's consider, in addition to our complete customization of the above functions? Does SpringBoot provide us with the ability to quickly modify media types based on configuration files? How to configure it? (Note: refer to the section on web development content negotiation in the official SpringBoot document)

5.0 view parsing and template engine

View parsing: SpringBoot does not support JSP by default. It needs to introduce third-party template engine technology to realize page rendering

5.1 view analysis

1. View analysis

  • forward
  • redirect
  • Custom view

1. View analysis principle and process

1. During the processing of the target method, all data will be placed in the ModelAndViewContainer. Include data and view addresses
2. ModelAndView (data and view address) will be returned after the execution of any target method
3. processDispatchResult() handles the dispatch result (how should the page respond)

  • 1,render(mv, request, response); Page rendering logic

    • 1. Get the View object according to some values (ViewName,) [defines the rendering logic of the page]

      • 1. All View parsers try to find the View object based on the current return value

      • 2. Get redirect: / main. HTML -- > thymeleaf new redirectview()

      • 3. The content negotiation view resolver contains all of the following view parsers. Internally, it uses all of the following view parsers to get view objects

      • 4,view.render(mv.getModelInternal(), request, response); The view object calls the custom render to render the page

      • How to render RedirectView [redirect to a page]

      • 1. Get destination url address

      • 2,response.sendRedirect(encodedURL);


    • The return value starts with forward: new internalresourceview (forwardurl); -- > Forward request.getRequestDispatcher(path).forward(request, response);
    • The return value starts with redirect: new redirectview() -- > render is redirect
    • The return value is a normal string: new ThymeleafView() – > render

Custom view parser + custom view: Dachang University

5.2 template engine - Thymeleaf

Modern, server-side Java template engine

1. Basic grammar

Variable value${...}Get request domain, session domain, object equivalent
Select variable*{...}Get context object value
news#{...}Get international equivalent
link@{...}Generate link
Fragment Expression~{...}jsp:include function to introduce public page fragments

Text values: 'one text', 'Another one!'
Numbers: 0, 34, 3.0, 12.3
Boolean: true, false
Null value: null
Variables: one and two variables cannot have spaces

Text operation
String splicing:+
Variable replacement: The name is ${name}

Mathematical operation
+ , - , * , / , %

Boolean operation
and, or, !, not

Comparison operation
Comparison: >, <, > =, < = (GT, lt, Ge, le * *) * equation: = == ( eq , ne )

Conditional operation
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)

2. Set attribute value - th:attr

<img src="../../images/gtvglogo.png"  th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
Alternative writing
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
<form action="subscribe.html" th:action="@{/subscribe}">

All h5 compatible label writing:

3. Iteration

<tr th:each="prod : ${prods}">
    <td th:text="${prod.name}">Onions</td>
    <td th:text="${prod.price}">2.41</td>
    <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
  <td th:text="${prod.name}">Onions</td>
  <td th:text="${prod.price}">2.41</td>
  <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>

4. Conditional operation

<a href="comments.html"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
<div th:switch="${user.role}">
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
  <p th:case="*">User is some other thing</p>

5. Attribute priority
Priority is not defined in writing order. When there are multiple th: * attributes in the same tag, thyclear also has the problem of priority when dealing with these attributes

1Fragment inclusionth:include th:replace
2Fragment iterationth:each
3Conditional evaluationth:if th:unless th:switch th:case
4Local variable definitionth:object th:with
5General attribute modificationth:attr th:attrprepend th:attrappend
6Specific attribute modificationth:value th:href th:src ...
7Text (tag body modification)th:text th:utext
8Fragment specificationth:fragment
9Fragment removalth:remove

5.3 use of thymeleaf

1. Introduce starter


thymeleaf is automatically configured

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
public class ThymeleafAutoConfiguration { }

Automatically configured strategy

  • 1. All thymeleaf configuration values are in thymeleaf properties

  • 2. Spring template engine is configured

  • 3. With ThymeleafViewResolver

  • 4. We just need to develop the page directly

public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";  // xxx.html

5.4 construction of background management system

1. Create a project and put all static resources under the static folder

2. Path construction

3. Template extraction
th:insert/replace/include * * pay attention to the differences between the three. Wrap the content to be extracted with div**

<head th:fragment="commonheader">

    <link href="css/style.css" rel="stylesheet" th:href="@{/css/style.css}">
    <link href="css/style-responsive.css" rel="stylesheet" th:href="@{/css/style-responsive.css}">
    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="js/html5shiv.js" th:src="@{/js/html5shiv.js}"></script>
    <script src="js/respond.min.js" th:src="@{/js/respond.min.js}"></script>

<div id="leftmenu" class="left-side sticky-left-side"> ... </div>

========= main.html =========
<div th:include="common :: commonheader"></div>
<!--Because use id statement, So use # Selector to select -- >
<div th:replace="common :: #leftmenu"></div>

4. Page Jump

public String main(User user, HttpSession session, Model model){
    if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
        //Save the users who log in successfully
        //Login successfully redirected to main.html; Redirection prevents duplicate form submissions
        return "redirect:/main";
    }else {
        model.addAttribute("msg","Account password error");
        //Return to the login page
        return "login";

5. Data rendering

public String dynamic_table(Model model){
    //Traversal of table contents
    List<User> users = Arrays.asList(new User("zhangsan", "123456"),
                                     new User("lisi", "123444"),
                                     new User("haha", "aaaaa"),
                                     new User("hehe ", "aaddd"));
    return "table/dynamic_table";
        <th>user name</th>
    <tr class="gradeX" th:each="user, userstat:${users}">
        <td th:text="${userstat.count}">Trident</td>
        <td th:text="${user.userName}">Internet</td>

6.0 interceptors

6.1 HandlerInterceptor interface

  • Write an interceptor to implement the HandlerInterceptor interface
  • Register the interceptor in the container (implement addinterceptors of webMvcConfigurer)
  • Specify the interception rule [if all static resources are intercepted, they will also be intercepted]
public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        log.info("preHandle The intercepted request path is{}",requestURI);
        // Login judgment
        HttpSession session = request.getSession();
        Object obj = session.getAttribute("user");
        if(obj != null) {
            return true;
        // Forward request to landing page
        request.setAttribute("msg", "Please log in first");
        request.getRequestDispatcher("/").forward(request, response);
        return false;
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        log.info("postHandle implement{}",modelAndView);
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                         @Nullable Exception ex) {
        log.info("afterCompletion Execution exception{}",ex);
============== AdminWebConfig ==============
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/images/**", "/js/**");

6.2 interceptor principle

1. According to the current request, find * * HandlerExecutionChain [* * handlers that can handle requests and all interceptors of handlers]

2. Execute the preHandle methods of all interceptors sequentially first

  • If the current interceptor prehandler returns true, the prehandler of the next interceptor will be executed
  • If the current interceptor returns false, execute the afterCompletion of all interceptors that have been executed in reverse order

3. If any interceptor returns false, it will jump out without executing the target method

4. All interceptors return True. Execute the target method

5. Execute the postHandle methods of all interceptors in reverse order.

6. Any exception in the previous steps will trigger afterCompletion in reverse order

7. After the page is successfully rendered, afterCompletion will also be triggered in reverse order

7.0 file upload

7.1 forms

<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="exampleInputEmail1">mailbox</label>
        <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
    <div class="form-group">
        <label for="exampleInputPassword1">name</label>
        <input type="text" name="username" class="form-control" id="exampleInputPassword1" placeholder="Password">
    <div class="form-group">
        <label for="exampleInputFile">head portrait</label>
        <input type="file" name="headerImg" id="exampleInputFile">
    <div class="form-group">
        <label for="exampleInputFile">Photo collection</label>
        <input type="file" name="photos" multiple>
    <button type="submit" class="btn btn-primary">Submit</button>

7.2 file upload code

  * MultipartFile Automatically encapsulate uploaded files
  * @param email
  * @param username
  * @param headerImg
  * @param photos
  * @return
public String upload(@RequestParam("email") String email,
                     @RequestParam("username") String username,
                     @RequestPart("headerImg") MultipartFile headerImg,
                     @RequestPart("photos") MultipartFile[] photos) throws IOException {
    log.info("Uploaded information: email={},username={},headerImg={},photos={}",

        //Save to file server, OSS server
        String originalFilename = headerImg.getOriginalFilename();
        headerImg.transferTo(new File("H:\\cache\\"+originalFilename));
    if(photos.length > 0){
        for (MultipartFile photo : photos) {
                String originalFilename = photo.getOriginalFilename();
                photo.transferTo(new File("H:\\cache\\"+originalFilename));
    return "main";

7.3 automatic configuration principle

File upload autoconfiguration class multipartautoconfiguration multipartproperties

  • The standardservlet multipartresolver [file upload parser] is automatically configured

  • Principle steps

    • When the request comes in, use the file upload parser to determine (isMultipart) and encapsulate (resolveMultipart, return MultipartHttpServletRequest) the file upload request

    • The parameter resolver (RequestPartMethodArgumentResolver) parses the file content in the request and encapsulates it into MultipartFile

    • **Encapsulate the file information in the request into a map** MultiValueMap<String, MultipartFile>

FileCopyUtils: copy the file stream

8.0 exception handling

8.1 error handling

1. Default rules

  • By default, Spring Boot provides / error mapping to handle all errors

  • For the machine client, it will generate a JSON response containing the details of the error, HTTP status and exception message. For the browser client, it will respond to a whitelabel error view and render the same data in HTML format

  • To customize it, add a View that resolves to error

  • To completely replace the default behavior, you can implement ErrorController and register the Bean definition of this type, or add a component of ErrorAttributes type to use the existing mechanism but replace its contents.

  • 4xx and 5xx pages under error / will be automatically parsed;
    2. Customize error handling logic

  • Custom error page

    • error/404.html, error/5xx.html; If there is an accurate error status code, the page will match accurately. If not, find 4xx.html; If none, trigger the white page
  • @ControllerAdvice + @ExceptionHandler handles global exceptions; The underlying layer is supported by ExceptionHandlerExceptionResolver

    public class GlobalExceptionHandler {
        @ExceptionHandler({ArithmeticException.class,NullPointerException.class})  //Handling exceptions
        public String handleArithException(Exception e){
            return "login"; //View address
  • @responsestatus + custom exception; The bottom layer is ResponseStatusExceptionResolver. The bottom layer calls response.senderror (statuscode, resolvedreason) with the information annotated by responsestatus; / error sent by Tomcat

    @ResponseStatus(value= HttpStatus.FORBIDDEN,reason = "Too many users")
    public class UserTooManyException extends RuntimeException {
        public  UserTooManyException(){}
        public  UserTooManyException(String message){
  • Spring underlying exceptions, such as parameter type conversion exceptions; DefaultHandlerExceptionResolver handles exceptions at the bottom of the framework

    • response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage())
  • Customize the implementation of HandlerExceptionResolver to handle exceptions; It can be used as the default global exception handling rule
    @Order(value= Ordered.HIGHEST_PRECEDENCE)  //Priority. The smaller the number, the higher the priority
    public class CustomerHandlerExceptionResolver implements HandlerExceptionResolver {
        public ModelAndView resolveException(HttpServletRequest request,
                                             HttpServletResponse response,
                                             Object handler, Exception ex) {
            response.sendError(511,"I like mistakes"); // try - catch
            return new ModelAndView();
  • ErrorViewResolver implements custom exception handling

    • Response.senderror: the error request will be forwarded to the controller

    • No one can handle your exception. The tomcat underlying response.sendError. error request will be forwarded to the controller

    • The page address that basicErrorController wants to go to is ErrorViewResolver

3. Automatic configuration principle of exception handling

  • ErrorMvcAutoConfiguration automatically configures exception handling rules
    • Components in container: Type: defaulterrorattributes - > ID: errorAttributes
      • public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver()
      • DefaultErrorAttributes: defines what data can be included in the error page
    • Component in container: Type: basicErrorController -- > ID: basicErrorController (json + white page adaptation response)
      • Handle the request for the default / error path; The page responds to new ModelAndView("error", model);
      • There is a component in the container. View - > ID is error * *; (response to default error page)**
      • **Put the component * * BeanNameViewResolver (View resolver) in the container; Use the returned View name as the id of the component to find the View object in the container.
    • Components in container: * * type: defaulterrorviewresolver - > ID: * * conventionErrorViewResolver
      • If an error occurs, the HTTP status code will be used as the view page address (viewName) to find the real page
      • error/404,5xx.html

If you want to return to the page; You will find the error view (static view) (a white page by default)

4. Exception handling steps and processes

  1. Execute the target method. Any exception during the operation of the target method will be caught and mark the end of the current request; And the exception will be assigned to dispatchException

  2. Enter the view parsing process (page rendering)

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

  1. mv = processHandlerException; Handle the exception occurred in handler, and return ModelAndView after processing;
  • Traverse all handlerExceptionResolvers to see who can handle the current exception [HandlerExceptionResolver handler exception resolver]

System default exception parser

1. DefaultErrorAttributes handles the exception first. Save the exception information to the rrequest field and return null

HadnlerExceptionResolverComposite { 0. ExceptionHandlerExceptionResolver 1. ResponseStatusExceptionResolver 2. DefaultHandlerExceptionResolver }

2. By default, no one can handle exceptions, so exceptions will be thrown

  • 1. If no one can handle it, the bottom layer will send the / error request. Will be handled by the underlying BasicErrorController

  • 2. Parse error view; Traverse all errorviewresolvers to see who can resolve them

  • 3. The ErrorViewResolver in the default DefaultErrorViewResolver takes the response status code as the address of the error page, error/500.html

  • 4. The template engine finally responds to this page error/500.html

9.0 Web native three component injection

9.1 using Servlet API

@ServletComponentScan(basePackages = "com.atguigu.admin"): specifies where the native Servlet components are placed
@WebServlet(urlPatterns = "/ my"): effect: direct response without Spring interceptor

====== Servlet ======
//@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet { // Implementation method}
====== Filter ======
//@WebFilter(urlPatterns={"/css/*","/images/*"}) // my
public class MyFilter implements Filter { // Implementation method}
====== lisenter ======
public class MySwervletContextListener implements ServletContextListener { // Implementation method}

It is recommended to use the RegistrationBean method
ServletRegistrationBean, FilterRegistrationBean, and ServletListenerRegistrationBean

====== MyRegistConfig ======
// (proxyBeanMethods = true): ensure that the dependent components are always single instance
@Configuration(proxyBeanMethods = true)
public class MyRegistConfig {
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/my","/my02");
    public FilterRegistrationBean myFilter(){
        MyFilter myFilter = new MyFilter();
//        return new FilterRegistrationBean(myFilter,myServlet());
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        return filterRegistrationBean;
    public ServletListenerRegistrationBean myListener(){
        MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();
        return new ServletListenerRegistrationBean(mySwervletContextListener);

Extension: how to register DispatchServlet

  • The DispatcherServlet property is automatically configured in the container and bound to WebMvcProperties; The corresponding configuration file configuration item is spring.mvc.

  • Configure DispatcherServlet through servletregistrationbean < DispatcherServlet >.

  • The default mapping is / path.

Multiple servlets can handle the same layer path, and the principle of accurate optimization

10.0 embedded Servlet container

10.1 switching embedded servlet containers

  • Default supported webServer

    • Tomcat, Jetty, or Undertow
    • The servletwebserver ApplicationContext container starts looking for the ServletWebServerFactory and guides the creation of the server
  • Switch server



    • SpringBoot application startup found that it is currently a web application. Web scenario package - Import tomcat
    • The web application will create a web version of the ioc container servletwebserver ApplicationContext
    • When the servlet webserver ApplicationContext is started, look for the servlet webserverfactory (servlet's web server factory -- > servlet's web server)
    • There are many WebServer factories at the bottom of SpringBoot by default; TomcatServletWebServerFactory, JettyServletWebServerFactory, or UndertowServletWebServerFactory
    • There will be an automatic configuration class directly at the bottom: ServletWebServerFactoryAutoConfiguration
    • ServletWebServerFactoryAutoConfiguration imported ServletWebServerFactoryConfiguration (configuration class)
    • The ServletWebServerFactoryConfiguration configuration class dynamically determines which Web Server package is imported into the system. (the default is to import the tomcat package from the web starter), and there is TomcatServletWebServerFactory in the container
    • Tomcat servlet webserverfactory creates a Tomcat server and starts it; The constructor of Tomcat webserver has the initialization method initialize---this.tomcat.start();
    • The embedded server is to manually call the code that starts the server (the tomcat core jar package exists)

10.2 custom Servlet container

  • Implement webserverfactorycustomizer < configurableservletwebserverfactory >
    • Bind the value of the configuration file to the servlet webserverfactory
  • Modify the configuration file server.xxx
  • Directly customize ConfigurableServletWebServerFactory

Xxxxxxcustomizer: a customizer that can change the default rules of xxxx

public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    public void customize(ConfigurableServletWebServerFactory server) {

11.0 customization principle

Customization method:

  • Modify the configuration file;

  • xxxxxCustomizer;

  • Write a custom configuration class xxxConfiguration; +@ Bean replaces and adds default components in the container; view resolver

  • Write a configuration class for a web application to implement WebMvcConfigurer to customize web functions; +@ Bean extends some more components to the container (important)

    public class AdminWebConfig implements WebMvcConfigurer

@EnableWebMvc + WebMvcConfigurer - @ Bean can fully take over spring MVC, and all rules can be reconfigured by itself; Realize customization and extension functions

  • 1. Webmvcoautoconfiguration default spring MVC auto configuration function class, static resources, welcome page
  • 2. Once @ EnableWebMvc is used, it will @ Import (DelegatingWebMvcConfiguration.class)
  • 3. DelegatingWebMvcConfiguration only guarantees the most basic use of spring MVC
    • Bring the webmvcconfigurers in all systems. The customization of all functions takes effect when these webmvcconfigurers are combined
    • Some very low-level components are automatically configured. RequestMappingHandlerMapping and the components that these components depend on are obtained from the container
    • public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
  • 4. The configuration in webmvcconfiguration must be @ ConditionalOnMissingBean(WebMvcConfigurationSupport.class) to be effective
  • 5. @ EnableWebMvc caused webmvcoautoconfiguration not to take effect

How to analyze the principle

Scenario starter - xxxautoconfiguration - Import xxx components - bind xxxProperties - bind profile items

Tags: Java Spring Boot

Posted on Fri, 15 Oct 2021 16:22:42 -0400 by Invincible