Study Notes: Dark Horse Programmer SpringMVC

Article directory

1 Overview

Summary of notes:

  • Meaning: SpringMVC: Spring MVC is a module in Spring Framework for building Java-based web applications . SpringMVC is a presentation layer framework technology. SpringMVC is used to develop presentation layer functions.
  • MVC: Design pattern that divides an application into three main components: Model , View , and Controller
  • Features:
    1. lightweight
    2. loose coupling
    3. highly customizable
    4. Easy to test
    5. Integrate other technologies
    6. RESTful support

1.1 Meaning

​ Spring MVC is a module in the Spring Framework for building Java-based web applications. It provides a development method based on the MVC (Model-View-Controller) design pattern to help developers build flexible and scalable web applications.

​ Spring MVC processes Web requests by dispatching requests and responses to corresponding processors (Controllers), and presents the processing results to the user. It adopts a loosely coupled design, allowing developers to separate the application's business logic and user interface, providing better code organization and maintainability.

image-20230814221014724

illustrate:

  • SpringMVC is a lightweight web framework based on Java that implements the MVC model.

  • advantage

    • Simple to use and convenient to develop (compared to Servlet)
    • High flexibility
  • SpringMVC, Servlet development that replaces the presentation layer of the back-end server

image-20230527102146297

illustrate:

​ SpringMVC’s performance method is more concise than Servlet development

1.2MVC design pattern

image-20230814102502858

​ MVC是一种软件设计模式,它将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。这种模式的目标是将应用程序的逻辑、数据和表示分离,以提高代码的可维护性重用性灵活性

  • 模型(Model):模型表示应用程序的数据和业务逻辑。它负责处理数据的读取、存储、验证以及处理业务规则。模型不直接与视图进行交互,而是通过控制器来传递数据
  • 视图(View):视图负责展示模型的数据给用户。它通常是用户界面的一部分,可以是网页、图形界面、命令行界面等。视图接收来自控制器的数据并将其呈现给用户
  • 控制器(Controller):控制器处理用户的请求并相应地更新模型和视图。它接收用户输入(例如点击按钮、提交表单等),根据输入调用适当的模型逻辑来更新数据,并将更新后的数据发送给视图进行显示

The core idea of ​​the MVC pattern is to separate different functional parts of the application and make them independent and replaceable. This separation makes the code easier to understand , maintain , and extend . It also promotes teamwork because developers can work on different parts of the model, view, and controller at the same time without interfering with each other. The MVC pattern is widely used in various software development frameworks and technologies, including web development frameworks such as Spring MVC, Ruby on Rails, etc.

1.3 Spring MVC features

​ Spring MVC is a Java-based web framework that is part of the Spring framework and is used to develop flexible and scalable web applications. The following are some features of Spring MVC:

  1. Lightweight: Spring MVC adopts a POJO-based development model and does not rely on any specific application server, so it is very lightweight.

  2. Loose coupling: Spring MVC is tightly integrated with the Spring framework, taking advantage of Spring's dependency injection and aspect-oriented programming features to achieve loose coupling between components.

  3. Highly customizable: Spring MVC provides rich configuration options and extensible interfaces, and developers can customize and configure various components according to needs to meet specific application requirements.

  4. Easy to test: Spring MVC adopts the MVC design pattern to separate business logic, data processing and user interface, making unit testing and integration testing easier.

  5. Powerful request processing: Spring MVC provides a flexible and powerful request processing mechanism. Request mapping, parameter binding, data verification, view parsing, etc. can be easily defined through annotations and configuration files.

  6. Diversity of view technologies: Spring MVC supports a variety of view technologies, including JSP, Thymeleaf, Freemarker, Velocity, etc. Developers can choose the appropriate view technology according to project needs.

  7. Integrate other technologies: Spring MVC can be seamlessly integrated with other technologies and frameworks, such as Spring Security to implement security authentication and authorization, Spring Data to access databases, Spring Boot to simplify configuration, etc.

  8. RESTful support: Spring MVC provides good support for RESTful style development, making it easy to create and manage RESTful style APIs.

Overall, Spring MVC has the advantages of flexibility, customizability, and testability, making it one of the preferred frameworks for developing web applications.

2. Basic use cases-SpringMVC basic application

Summary of notes:

  • Steps
    1. Import servlet-api, spring-webmvcdependency coordinates
    2. Create a SpringMVC controller class (equivalent to Servlet functionality)
    3. Create configuration file class
    4. Initialize the Servlet container to load the SpringMVC environment and set the requests processed by SpringMVC technology:
      • Description: Inherit AbstractDispatcherServletInitializerthis class, override three abstract methods, and AnnotationConfigWebApplicationContextload the file of the SpringMVC controller through
  • principle:
    • image-20230814221025847
    • Please see the next section for details
  • Annotation usage:
    • @Controller: Set the core controller bean of SpringMVC
    • @RequestMapping: Set the current controller method request access path
    • @ResponseBody: Set the current controller method response content to the current return value , no need to parse
    • @Configuration: identifies a class as a Spring configuration class . It is usually used in conjunction with other annotations to define the configuration information of the application.
    • @ComponentScan: Tell Spring to scan components (including classes, interfaces, annotations, etc.) in the specified package and register them as Spring beans

Step 1: To use SpringMVC technology, you need to import SpringMVC coordinates and Servlet coordinates first

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

illustrate:

  • SpringMVC coordinates, you can use the functions and features provided by Spring MVC, such as request processing, routing, data binding, and view parsing
  • By introducing Servlet coordinates, the functions of the Servlet container can be integrated into the project, allowing the project to process HTTP requests and generate responses .

Step 2: Create SpringMVC controller class (equivalent to Servlet function)

//定义表现层控制器bean
@Controller
public class UserController {
    
    

    //设置映射路径为/save,即外部访问路径
    @RequestMapping("/save")
    //设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
    @ResponseBody
    public String save() {
    
    
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }

    //设置映射路径为/delete,即外部访问路径
    @RequestMapping("/delete")
    @ResponseBody
    public String delete() {
    
    
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }
}

Replenish:

  1. Name: @Controller

    • Type: class annotation

    • Location: Above the SpringMVC controller class definition

    • Role: Set the core controller bean of SpringMVC

    • example:

      @Controller
      public class UserController {
               
               
      }
      
      
  2. Name: @RequestMapping

    • Type: method annotation

    • Location: Above the SpringMVC controller method definition

    • Function: Set the current controller method request access path

    • example:

      @RequestMapping("/save")
      public void save(){
               
               
          System.out.println("user save ...");
      }
      
    • Related properties

      • value (default): request access path
  3. Name: @ResponseBody

    • Type: method annotation

    • Location: Above the SpringMVC controller method definition

    • Function: Set the response content of the current controller method as the current return value without parsing

    • example:

      @RequestMapping("/save")
      @ResponseBody
      public String save(){
               
               
          System.out.println("user save ...");
          return "{'info':'springmvc'}";
      }
      

Step 3: Create a configuration file class

//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("love.ljtxy.controller")
public class SpringMvcConfig {
    
    
}

illustrate:

Initialize the SpringMVC environment (same as the Spring environment) and set SpringMVC to load the corresponding beans

Notice:

​ Here you only need to change the controller layer into a Bean, and no extra equipment is needed to scan the package.

Step 4: Initialize the Servlet container to load the SpringMVC environment and set the requests processed by SpringMVC technology

//web容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    
    
    //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
    protected WebApplicationContext createServletApplicationContext() {
    
    
        //初始化WebApplicationContext对象
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        //加载指定配置类
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    //设置由springmvc控制器处理的请求映射路径
    protected String[] getServletMappings() {
    
    
        return new String[]{
    
    "/"};
    }

    //加载spring配置类
    protected WebApplicationContext createRootApplicationContext() {
    
    
        return null;
    }
}

illustrate:

Define a configuration class for servlet container startup and load spring configuration in it

3. Process principle

Summary of notes:

  1. Start the server initialization process
  2. Web container initialization
  3. Servlet container initialization
  4. SpringMVC configuration class loading
  5. Load the beans corresponding to @ComponentScan
  6. Control layer bean loading
  7. Request processing

image-20230814221054845

  1. single request process

  2. send request

  3. request distribution

  4. Request parsing

  5. method distribution

  6. method execution

  7. Method return value processing

  8. Annotation usage:

  • @ComponentScan: Automatically scan the classes in the specified package and its sub-packages and identify them as Spring components. Dependency injection, automatic assembly
    • excludeFilters: exclude beans loaded in the scan path, you need to specify the category (type) and specific items (classes)
    • includeFilters: Load the specified bean, you need to specify the category (type) and specific items (classes)

3.1 Overview

​ In SpringMVC startup, the process is roughly divided into two types, one is called the startup server initialization process, and the other is called the single request process.

  • Start the server initialization process
    1. The server starts, executes the ServletContainersInitConfig class, and initializes the web container.
    2. Execute the createServletApplicationContext method to create the WebApplicationContext object
    3. Load SpringMvcConfig
    4. Execute @ComponentScan to load the corresponding bean
    5. Load UserController, each @RequestMapping name corresponds to a specific method
    6. Execute the getServletMappings method and define all requests through SpringMVC
  • single request process
    1. Send request localhost/save
    2. The web container finds that all requests go through SpringMVC and hands the request to SpringMVC for processing.
    3. Parse request path/save
    4. The corresponding method save() is executed by /save matching.
    5. Execute save()
    6. It is detected that @ResponseBody directly returns the return value of the save() method to the requester as the response body.

image-20230814103709269

illustrate:

The created WebApplicationContextobject will be placed in the ServletContext of the large Servelet request

3.2SpringMVC and Spring’s bean loading control

​ Under the com.itheima package, various beans are included, such as config, controller, etc. SpringMVC only controls the development of the Controller layer, and Spring controls the development of the config, service, and dao layers. However, specifying Spring's package scanning range as com.itheimaunder the package at this time will cause Spring to mistakenly load the SpringMVC beans.

image-20230530073206117

illustrate:

​ Exclude SpringMVC-controlled beans when loading Spring- controlled beans, thereby solving the problem of how to avoid Spring incorrectly loading into SpringMVC Beans due to different functions.

Supplement:

  • Spring MVC related beans ( presentation layer beans)
  • Spring controlled beans
    • Business bean (Service)
    • Function beans (DataSource, etc.)
  • SpringMVC related bean loading control
    • The packages corresponding to the beans loaded by SpringMVC are all in the com.itheima.controller package.
  • Spring related bean loading control
    • Method 1: Set the scanning range of the beans loaded by Spring to com.itheima, and exclude the beans in the controller package.
    • Method 2: Set the scanning range of beans loaded by Spring to a precise range , such as service packages, dao packages, etc.
    • Method 3: Do not distinguish between Spring and SpringMVC environments, load them into the same environment

3.3ServletContainersInitConfig.class

/**
 * Web容器配置类
 */
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    

    /**
     * 返回Spring应用程序的根配置类
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
    
    
        return new Class[]{
    
    SpringConfig.class};
    }

    /**
     * 返回Servlet的配置类
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
    
    
        return new Class[]{
    
    SpringMvcConfig.class};
    }

    /**
     * 返回DispatcherServlet的映射路径
     */
    @Override
    protected String[] getServletMappings() {
    
    
        return new String[]{
    
    "/"};
    }
}

Notice:

​ When using the getServletConfigClasses method, you need to configure the corresponding return value SpringMvcConfig.class, which is the configuration at the control layer.

3.4SpringConfig.class

@Configuration
@ComponentScan(value = "love.ljtxy",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                classes = Controller.class
        ))
public class SpringConfig {
    
    
}

illustrate:

  • Name: @ComponentScan
  • Type: class annotation
  • Attributes
    • excludeFilters: exclude beans loaded in the scan path, you need to specify the category (type) and specific items (classes)
    • includeFilters: Load the specified bean, you need to specify the category (type) and specific items (classes)

detail:

​ Because this annotation is in @ComponentScan, it can be @Filterdirectly used as an internal annotation..

3.5SpringMvcConfig.class

//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("love.ljtxy.controller")
public class SpringMvcConfig {
    
    

}

illustrate:

​ Here you only need to configure the SpringMVC control to scan only controllerthe packages of the layer. Because the configuration of SpringMVC replaces the control layer in Spring

4. Request and response

Summary of notes:

  1. Request mapping path: @RequestMapping: Set the current controller method request access path. If set, set the current controller method request access path prefix uniformly on the class.

  2. Request method:

  • Get request parameters
  • Post request parameters
  1. Post request Chinese garbled processing
// AbstractAnnotationConfigDispatcherServletInitializer 是 Spring Framework 中的一个类,它用于配置和初始化基于注解的 Spring MVC 应用程序
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
     
     
    // 配字符编码过滤器
    protected Filter[] getServletFilters() {
     
     
        CharacterEncodingFilter filter = new CharacterEncodingFilter(); //添加过滤器
        filter.setEncoding("utf-8"); //指定过滤器字符集
        return new Filter[]{
     
     filter};
    }
}
  1. Request parameters

  2. Ordinary parameters - same name : no configuration required

  3. Ordinary parameters with different names : You need to use **@RequestParam to bind parameter relationships**

  4. POJO parameters (key point): Define POJO type formal parameters to receive parameters directly without additional configuration . Note that the attribute names in the entity class need to be consistent. Suitable for regular form parameter binding!

  5. Nested POJO parameters: The request parameter name is the same as the formal parameter object attribute name . Nested POJO attribute parameters can be received according to the object hierarchy relationship.

  6. Array parameters: Define array type parameters to receive multiple parameters . Suitable for regular form parameter binding!

  7. The collection saves ordinary parameters: @RequestParam binds parameter relationships, for example@RequestParam List<String> likes

  8. Pass Json data

    1. Import coordinates:
    <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.9.0</version>
    </dependency>
    
    1. Set request parameters

    2. Enable support for automatic conversion of json data

    @Configuration
    @ComponentScan("com.itheima.controller")
    @EnableWebMvc // 在SpringMVC中需要开启Json数据自动类型转换,与SpringBoot不同
    public class SpringMvcConfig {
           
           
    }
    
  9. Pass Json objects : define POJO type parameters and use annotations @RequestBodyto receive parameters. Used when processing JSON data ! !

  10. Pass Json array : The json array data has the same name as the collection generic property. Define the List type parameter to receive the parameters. Used when processing JSON data ! !

  11. Date type parameter passing:

  • @DateTimeFormat (pattern = “yyyy - MM-dd”): Set the date and time data format
  1. Annotation explanation:
  • @RequestParam : Binds the relationship between request parameters and processor method parameters , often used for data processing between forms
  • @EnableWebMvc : Enable multiple auxiliary functions of SpringMVC
  • @RequestBody : Pass the data contained in the request body in the request to the request parameters. This annotation can only be used once per processor method. Commonly used for data processing between Json
  1. response:
  • Response page: return “page.jsp”;
  • Response data:
    • Text data: return "response text";
    • Json data: Use **@ResponseBody** to set the response to Json format . The bottom layer is to use the type converter HttpMessageConverter interface to correspond to different implementation classes, and then perform conversion

4.1 Request mapping path

@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    
    
        System.out.println("user save ...");
        return "{'module':'user save'}";
    }
}

illustrate:

Name: @RequestMapping

  • Type: method annotation class annotation

  • Location: Above the SpringMVC controller method definition

  • Function: Set the current controller method request access path. If set, set the current controller method request access path prefix uniformly on the class.

  • Attributes

    • value (default): request access path, or access path prefix

4.2 Request method

1.Get request parameters

image-20230530082533259

2.Post request parameters

image-20230530082552044

4.3 Post request Chinese garbled processing

// AbstractAnnotationConfigDispatcherServletInitializer 是 Spring Framework 中的一个类,它用于配置和初始化基于注解的 Spring MVC 应用程序
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
    
    
    // 配字符编码过滤器
    protected Filter[] getServletFilters() {
    
    
        CharacterEncodingFilter filter = new CharacterEncodingFilter(); //添加过滤器
        filter.setEncoding("utf-8"); //指定过滤器字符集
        return new Filter[]{
    
    filter};
    }
}

illustrate:

​ You need to add a filter in SpringMVC, just like in the Servlet request, you need to add a filter with request characters for the response request.

detail:

​ Add a filter to the web container and specify the character set. The Spring-web package provides a dedicated character filter.

Replenish:

More detailed reference: Analysis of AbstractAnnotationConfigDispatcherServletInitializer_Yan Demon King's Blog-CSDN Blog

4.4 Request parameters

Request parameters are data sent by the client (browser, mobile app, etc.) to the server to tell the server what to do or provide the required data.

4.4.1 Ordinary parameters - same name

​ The URL address is used to pass parameters. The address parameter name is the same as the formal parameter variable name . You can receive the parameters by defining the formal parameter.

image-20230530083541992

@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
    
    
    System.out.println("普通参数传递 name ==> "+name);
    System.out.println("普通参数传递 age ==> "+age);
    return "{'module':'common param'}";
}

4.4.2 Ordinary parameters - different names

​ The request parameter name is different from the formal parameter variable name. Use @RequestParam to bind the parameter relationship.

image-20230530083618242

@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name")String userName , int age){
    
    
    System.out.println("普通参数传递 userName ==> "+userName);
    System.out.println("普通参数传递 age ==> "+age);
    return "{'module':'common param different name'}";
}

detail:

​ If the request parameter name is different from the formal parameter variable name, you need to use @RequestParam to bind the parameter relationship. If they are the same, no need to specify

Replenish:

  • name: @RequestParam
    • Type: formal parameter annotation
    • Position: Before the formal parameter definition of the SpringMVC controller method
    • Function: Bind the relationship between request parameters and processor method parameters
  • parameter:
    • required: Whether it is a required parameter
    • defaultValue: parameter default value

4.4.3POJO parameters (key points)

​ The request parameter name is the same as the property name of the formal parameter object. You can receive parameters by defining a POJO type parameter. Suitable for regular form parameter binding

image-20230530083936860

@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    
    
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo param'}";
}

illustrate:

​ When using PoJo parameter passing, the value to be passed can be received if it corresponds to the attribute name in the object.

detail:

​ When using PoJo parameters to pass parameters, the SpringMVC framework will first obtain the constructor method according to the type of PoJo, first create the object, and then pass it according to the set method of the parameters.

4.4.4 Nested POJO parameters

​ The request parameter name is the same as the formal parameter object attribute name, and nested POJO attribute parameters can be received according to the object hierarchy relationship.

image-20230530084152345

@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
    
    
    System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
    return "{'module':'pojo contain pojo param'}";
}

4.4.5 Array parameters

​ If the request parameter name is the same as the formal parameter object attribute name and there are multiple request parameters, you can receive the parameters by defining an array type parameter.

image-20230530084413567

@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
    
    
    System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
    return "{'module':'array param'}";
}

4.4.6 Collection saves common parameters

​ If the request parameter name is the same as the formal parameter collection object name and there are multiple request parameters, @RequestParam binds the parameter relationship.

image-20230530084449696

@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
    
    
    System.out.println("集合参数传递 likes ==> "+ likes);
    return "{'module':'list param'}";
}

Notice:

​ If you use a collection to save ordinary parameters, the SpringMVC framework will pass the collection as a PoJo object. And the collection has no construction method, so an error will be reported.

image-20230530085326930

At this point, after adding @RequestParamannotations, the SpringMVC framework will directly put the parameters involved in the request into the collection.

4.4.7 Basic use case-steps of passing Json data

Step 1: Add json data conversion related coordinates

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.0</version>
</dependency>

Step 2: Set up sending json data (add json data in the request body)

image-20230530090141109

Step 3: Enable support for automatic conversion of json data

@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc // 在SpringMVC中需要开启Json数据自动类型转换,与SpringBoot不同
public class SpringMvcConfig {
    
    
}

illustrate:

​ @EnableWebMvc annotation is powerful. This annotation integrates multiple functions. Only part of it is used here, that is, automatic type conversion of json data.

Replenish:

  • Name: @EnableWebMvc
    • Type: configuration class annotation
    • Location: Above the SpringMVC configuration class definition
    • Function: Enable multiple auxiliary functions of SpringMVC

Step 4: Set up to receive json data

@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
    
    
    System.out.println("list common(json)参数传递 list ==> "+likes);
    return "{'module':'list common for json param'}";
}

illustrate:

Name: @RequestBody

  • Type: formal parameter annotation
  • Position: Before the formal parameter definition of the SpringMVC controller method
  • Function: Pass the data contained in the request body in the request to the request parameters. This annotation can only be used once per processor method.

4.4.8 Pass Json object (emphasis)

​ The json data has the same property name as the formal parameter object, and the parameters can be received by defining the POJO type parameter. Used when processing JSON data

image-20230530090604255

premise:

  • Add json data conversion related coordinates
  • Enable support for automatic conversion of json data
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
    
    
    System.out.println("pojo(json)参数传递 user ==> "+user);
    return "{'module':'pojo for json param'}";
}

4.4.9 Pass Json array

​ The json array data has the same name as the collection generic property. Define the List type parameter to receive the parameters.

image-20230530090734676

@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
    
    
    System.out.println("list pojo(json)参数传递 list ==> "+list);
    return "{'module':'list pojo for json param'}";
}

Note: The following prerequisites are required

  • Add json data conversion related coordinates
  • Enable support for automatic conversion of json data

4.5 Date type parameter transfer

  • Date type data has different formats based on different systems.
    • 2088-08-18
    • 2088/08/18
    • 08/18/2088
  • When receiving formal parameters, set different reception methods according to different date formats
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
                        @DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
                        @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")Date date2){
    
    
    System.out.println("参数传递 date ==> "+date);
    System.out.println("参数传递 date(yyyy-MM-dd) ==> "+date1);
    System.out.println("参数传递 date(yyyy/MM/dd HH:mm:ss) ==> "+date2);
    return "{'module':'data param'}";
}

illustrate:

  • ask:

    http://localhost/dataParam?date=2088/08/08&date1=2088-08-18&date2=2088/08/28 8:08:08
    

Replenish:

  • Name: @DateTimeFormat
    • Type: formal parameter annotation
    • Position: in front of the SpringMVC controller method parameters
    • Function: Set date and time data format
    • Attributes:
      • pattern: date and time format string

Note: Type conversion function needs to be enabled on the configuration class

  • Name: @EnableWebMvc

  • Function: Matching the corresponding type converter according to the type is one of the functions of this annotation

Extension: parameters are passed through annotations, and the internal work is actually implemented through the Converter interface.

  • Converter interface

    public interface Converter<S, T> {
           
           
        @Nullable
        T convert(S var1);
    }
    
  • Request parameter age data (String→Integer)

  • json data to object (json → POJO)

  • Date format conversion (String → Date)

image-20230530141442994

Convert has so many implementation classes to convert data types

4.6 Response

4.6.1 Overview

​The response is the message returned by the server to the client to provide the data required for the request or the result of performing the operation.

Response classification:

  1. response page
  2. response data
    • text data
    • json data

4.6.2 Response page (understand)

@RequestMapping("/toPage")
public String toPage(){
    
    
    return "page.jsp";
}

4.6.3 Response text data (understanding)

@RequestMapping("/toText")
@ResponseBody
public String toText(){
    
    
    return "response text";
}

Replenish:

  • Name: @ResponseBody
    • Type: method annotation
    • Location: Above the SpringMVC controller method definition
    • Function: Set the current controller return value as the response body

Notice:

​ When using @ResponseBody to respond to content, you need to add

4.6.4 Respond to Json data (object to Json)

@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
    
    
    User user = new User();
    user.setName("赵云");
    user.setAge(41);
    return user;
}

Replenish:

  • Type converter HttpMessageConverter interface

    public interface HttpMessageConverter<T> {
           
           
       boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
       boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
       List<MediaType> getSupportedMediaTypes();
       T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
             throws IOException, HttpMessageNotReadableException;
       void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
             throws IOException, HttpMessageNotWritableException;
    }
    

    ​ When using the @ResponseBody annotation to respond to content, it is not converted through the Converter interface, but through a new interface HttpMessageConverter接口.

4.6.5 Respond to Json data (convert object collection to Json array)

@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
    
    
    User user1 = new User();
    user1.setName("赵云");
    user1.setAge(41);
    User user2 = new User();
    user2.setName("master 赵云");
    user2.setAge(40);
    List<User> userList = new ArrayList<User>();
    userList.add(user1);
    userList.add(user2);
    return userList;
}

5. REST style

Summary of notes:

  1. Overview: REST (Representational State Transfer) is a software architecture style that focuses on the status of resources and the interaction between resources.

  2. Set HTTP request action (verb): @RequestMapping(value = “xxx”, method = RequestMethod.POST )

  3. Set request parameters (path variable): @RequestMapping( value = “/users/{id}” , method = xxxx)

  4. RESTful rapid development:

    • @RestController: Set the current controller class to RESTful style, which is equivalent to the combined function of @Controller and @ResponseBody annotations

      @RestController
      public class BookController {
               
               
      }
      
    • @GetMapping @PostMapping @PutMapping @DeleteMapping: Set the current controller method request access path and request action

      @GetMapping("/{id}")
      public String getById(@PathVariable Integer id){
               
               }
      

5.1 Overview

REST (Representational State Transfer) is a software architectural style for designing distributed systems of web applications. It mainly focuses on the status of resources and the interaction between resources , which is achieved by using a unified interface and various methods of the HTTP protocol.

  • Traditional style resource description form

    http://localhost/user/getById?id=1

    http://localhost/user/saveUser

  • REST style description form

    http://localhost/user/1

    http://localhost/user

advantage:

  • Hide the access behavior of resources. It is impossible to know what operations are performed on the resources through the address.
  • writing simplification

Introduction to REST Style

image-20230530150231874

5.2 Set HTTP request action (verb)

@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public String save(@RequestBody User user){
    
    
    System.out.println("user save..." + user);
    return "{'module':'user save'}";
}

@RequestMapping(value = "/users" ,method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
    
    
    System.out.println("user update..."+user);
    return "{'module':'user update'}";
}

Replenish:

  • Name: @RequestMapping
    • Type: method annotation
    • Location: Above the SpringMVC controller method definition
    • Role: set the current controller method request access path
    • Attributes
      • value (default): request access path
      • method: http request action, standard action (GET/POST/PUT/DELETE)

5.3 Set request parameters (path variables)

@RequestMapping(value = "/users/{id}" ,method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
    
    
    System.out.println("user delete..." + id);
    return "{'module':'user delete'}";
}

Replenish:

  • Name: @PathVariable
    • Type: formal parameter annotation
    • Position: Before the formal parameter definition of the SpringMVC controller method
    • Function: bind the relationship between the path parameter and the formal parameter of the processor method, requiring a one-to-one correspondence between the path parameter name and the formal parameter name

5.4RESTful rapid development

Name: @RestController

  • Type: class annotation

  • Location: Above the controller class definition for RESTful development based on SpringMVC

  • Function: Set the current controller class to RESTful style, which is equivalent to the combination of @Controller and @ResponseBody annotations

  • example:

    @RestController
    public class BookController {
          
          
    }
    

名称:@GetMapping @PostMapping @PutMapping @DeleteMapping

  • Type: method annotation

  • Location: Above the RESTful development controller method definition based on SpringMVC

  • Function: Set the current controller method request access path and request action, each corresponding to a request action, for example, @GetMapping corresponds to GET request

  • example:

    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
          
          
        System.out.println("book getById..."+id);
        return "{'module':'book getById'}";
    }
    
  • Attribute: value (default): request access path

5.5 Basic case-data interaction based on RESTful page

Step Zero: Building the Basic Environment

image-20230530194836763

Step 1: Make a SpringMVC controller and test the interface function through PostMan

illustrate:

​ The same 基本用例-SpringMVC基础应用process, will not be shown here.

Step 2: Set access permission for static resources

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    
    
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
        //当访问/pages/????时候,走/pages目录下的内容
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

illustrate:

When accessing web resources, because the ServletContainersInitConfig class in step zero is configured with the getServletMappings method as interception /and path, when accessing static resources in the webapp directory, the request will be intercepted by SpringMVC.

protected String[] getServletMappings() {
     
     
return new String[]{
     
     "/"};
}

At this point, there are many processing methods. You can create a new class, inherit WebMvcConfigurationSupport and then override the addResourceHandlers method to add resource handlers. When processing resources, just access /xx/**the resources under the accessed path to /xx/the resource directory.

Notice:

​ When this request is configured, SpringMVC must be loaded to load this configuration

Step 3: Load resource request configuration

//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan({
    
    "love.ljtxy.controller","love.ljtxy.config"})
@EnableWebMvc
public class SpringMvcConfig {
    
    

}

illustrate:

At this point, add a new scan class

6.SSM integration (key)

Summary of notes: This section is the focus, please check each section for details

6.1 Overview

Summary of notes:

  • Meaning: The SSM framework is an integration of Spring, Spring MVC, and Mybatis framework , and is a standard MVC pattern . The standard SSM framework has four layers, namely dao layer (mapper), service layer, controller layer and View layer.

  • Persistence layer: The dao layer (mapper) layer is mainly responsible for the work of the data persistence layer. Some tasks responsible for communicating with the database are encapsulated here.

  • Business layer: Service layer. The Service layer is mainly responsible for the logical application design of business modules .

  • Presentation layer: Controller layer (Handler layer), responsible for the control of specific business module processes .

  • View layer: View layer, mainly integrated with the control layer, is mainly responsible for the presentation of the front-end jsp page .

  • Relationship interaction diagram:

    image-20230601092944922

​ The SSM framework is an integration of spring, spring MVC, and mybatis framework. It is a standard MVC pattern. The standard SSM framework has four layers, namely dao layer (mapper), service layer, controller layer and View layer. Use spring to implement business object management, use spring MVC to be responsible for request forwarding and view management, and mybatis as the persistence engine for data objects.

1) Persistence layer: Dao layer (mapper) layer
Function: Mainly responsible for the work of the data persistence layer, some tasks responsible for communicating with the database are encapsulated here.

  • The Dao layer first designs the interface, and then defines the implementation class of the interface in the Spring configuration file.
  • Then the interface can be called in the module to process the data business. (You no longer care which class the implementation class of the interface is)
  • The configuration of the data source and the parameters related to the database connection are configured in the Spring configuration file.

2) Business layer: Service layer
Function: The Service layer is mainly responsible for the logical application design of the business module.

  • Design the interface first, then design the actual class, and then configure its implementation association in the Spring configuration file. (The implementation of the business logic layer must specifically call the Dao interface that has been defined by itself.) In this way, the Service interface can be called in the application for business processing.
  • After establishing Dao, establish the service layer. The service layer must be under the controller layer because it must not only call the interface of the Dao layer but also provide the interface to the controller layer. Each model has a service interface, and each interface encapsulates its own business processing methods.

3) Presentation layer: Controller layer (Handler layer)
role: responsible for the control of specific business module processes .

  • Configuration is also done in Spring’s configuration file.
  • Call the interface provided by the Service layer to control the business process.
  • Different business processes will have different controllers. In specific development, our processes can be abstractly summarized and sub-unit process modules can be designed that can be reused.

4) View layer
Function: It is mainly closely integrated with the control layer and is mainly responsible for the presentation of the front-end jsp page.

6.2 Integrated configuration

Summary of notes:

  • Step 1: Import dependencies
  • Step 2: Create the basic directory structure
  • Step 3: Write the JdbcConfig class
    • Create DruidDataSource as data source
    • Create DataSourceTransactionManager as transaction manager
  • Step 4: Write the MyBatisConfig class
    • Configure SqlSessionFactoryBean for creating SqlSessionFactory instances
    • Configure MapperScannerConfigurer to automatically scan and register the Mapper interface of MyBatis
  • Step 5: Write the ServletConfig class
    • Get the root configuration class of Spring, used to configure the Spring container
    • Get the SpringMVC configuration class, used to configure the SpringMVC container
    • Get the mapping path of DispatcherServlet
  • Step 6: Write the SpringConfig class
    • Scan components and beans under the specified package
    • Load the jdbc.properties property file
    • Import JdbcConfig and MyBatisConfig configuration classes
    • open transaction
  • Step 7: Write the SpringMvcConfig class
    • Scan the package where the controller component is located
    • Enable Spring MVC features

Please check this section for details

Step 1: Import dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

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

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.15.0</version>
</dependency>

illustrate:

​ These are some regular SSM integration dependencies, among which javax.servlet-api is a Servlet request interaction dependency, spring-webmvc is a control layer replacement dependency, mybatis and mybatis-spring are SpringMVC integration MyBatis dependencies, druid and spring-jdbc are used Spring provides data source operation dependencies, and jackson-core is used for conversion of response data and received data

Step 2: Create the basic directory structure

image-20230531074500917

Step 3: Write the JdbcConfig class

public class JdbcConfig {
    
    
    // 注入jdbc.driver配置项的值
    @Value("${jdbc.driver}")
    private String driver;
    // 注入jdbc.url配置项的值
    @Value("${jdbc.url}")
    private String url;
    // 注入jdbc.username配置项的值
    @Value("${jdbc.username}")
    private String username;
    // 注入jdbc.password配置项的值
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
    
    
        // 创建DruidDataSource作为数据源
        DruidDataSource dataSource = new DruidDataSource();
        // 配置数据源的驱动类
        dataSource.setDriverClassName(driver);
        // 配置数据源的URL
        dataSource.setUrl(url);
        // 配置数据源的用户名
        dataSource.setUsername(username);
        // 配置数据源的密码
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
    
    
        // 创建DataSourceTransactionManager作为事务管理器
        DataSourceTransactionManager ds = new DataSourceTransactionManager();
        // 设置事务管理器使用的数据源
        ds.setDataSource(dataSource);
        return ds;
    }
}

illustrate:

Through the above injection operation, the attribute values ​​related to the database connection in the configuration file can be injected into the corresponding fields. In this way, other components that need to use the data source can obtain the data source bean through dependency injection, thereby obtaining the database connection for operation and transaction management.

Step 4: Write the MyBatisConfig class

public class MyBatisConfig {
    
    

    /**
     * 配置SqlSessionFactoryBean,用于创建SqlSessionFactory实例
     * @param dataSource 数据源
     * @return SqlSessionFactoryBean实例
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
    
    
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setTypeAliasesPackage("love.ljtxy.entity"); // 设置实体类的别名包路径
        return factoryBean;
    }

    /**
     * 配置MapperScannerConfigurer,用于自动扫描并注册MyBatis的Mapper接口
     * @return MapperScannerConfigurer实例
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
    
    
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("love.ljtxy.mapper"); // 设置Mapper接口的包路径
        return msc;
    }
}

illustrate:

By introducing this configuration class into the Spring configuration file, the relevant configuration of MyBatis can be completed, so that applications can easily use MyBatis for database operations.

Step 5: Write the ServletConfig class

public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    

    /**
     * 获取Spring的根配置类,用于配置Spring容器
     * @return 根配置类数组
     */
    protected Class<?>[] getRootConfigClasses() {
    
    
        return new Class[]{
    
    SpringConfig.class};
    }

    /**
     * 获取SpringMVC的配置类,用于配置SpringMVC容器
     * @return SpringMVC配置类数组
     */
    protected Class<?>[] getServletConfigClasses() {
    
    
        return new Class[]{
    
    SpringMvcConfig.class};
    }

    /**
     * 获取DispatcherServlet的映射路径
     * @return 映射路径数组
     */
    protected String[] getServletMappings() {
    
    
        return new String[]{
    
    "/"};
    }
}

illustrate:

By automatically loading the Servlet configuration class when the Web container starts, the initialization and configuration of Spring and SpringMVC containers can be completed, so that the application can handle Web requests and perform corresponding processing.

Replenish:

​ SpringMVC container can access Spring container. The Spring container cannot access the SpringMVC container. Because Spring's IOC container is set here as the parent container of Spring MVC's IOC container

image-20230602093019060

Step 6: Write the SpringConfig class

@Configuration
@ComponentScan("love.ljtxy.service") // 扫描指定包下的组件和Bean
@PropertySource("classpath:jdbc.properties") // 加载jdbc.properties属性文件
@Import({
    
    JdbcConfig.class, MyBatisConfig.class}) // 导入JdbcConfig和MyBatisConfig配置类
@EnableTransactionManagement //开启事务
public class SpringConfig {
    
    
}

Notice:

​ When Spring uses transactions, you need to use annotations @EnableTransactionManagementto enable transactions

illustrate:

​Through these configurations, the Spring container can load and manage components and beans under the specified package path, and can import other configuration classes as needed to achieve flexible configuration and assembly.

Replenish:

  • @ImportAnnotation is a meta-annotation in Spring Framework, which is used to import other configuration classes into the current configuration class in order to combine the functions of multiple configuration classes. Through @Importannotations, other configuration classes can be loaded into the Spring container as bean definitions.
  • Annotations can be used @PropertySourceto easily manage and load attribute values ​​in property files, making the attribute values ​​in configuration classes more flexible and configurable.

Step 7: Write the SpringMvcConfig class

@Configuration
@ComponentScan("love.ljtxy.controller") // 扫描控制器组件所在的包
@EnableWebMvc // 启用Spring MVC功能
public class SpringMvcConfig {
    
    
}

illustrate:

​ Through the above configuration, Spring MVC can automatically scan the controller classes under the specified package and provide annotation-based request mapping, parameter parsing, view parsing and other functions, making the development of Web applications more convenient and efficient.

6.3 Function module development

Summary of notes:

  • Step 1: Write the entity class
  • Step 2: Write Dao layer interface
    • @Insert, @Update, @Delete, @Selectannotations associate SQL statements with methods.
    • The SQL statement in the annotation uses placeholders #{propertyName}to reference the attribute values ​​of the object to implement dynamic parameter binding.
  • Step 3: Write Service interface
    • Generally speaking, when writing the Service interface layer, you need to know the name and meaning.
    • Generally speaking, when writing an interface, you need to return the operation results of this service
  • Step 4: Write the Service interface implementation layer
    • Generally speaking, after writing the Service implementation class, you can test the methods of the Service layer.
  • Step 5: Test the Service layer
    • @RunWithAnnotations are used to specify test runner (test runner), which tells JUnit to use a specific runner to execute the test when running the test.
    • @ContextConfigurationAnnotations are used to specify the configuration information of the Spring container and tell JUnit which configurations to load before running the test.
  • Write the presentation layer

Step 1: Write the entity class

@Date
public class Book {
    
    
    private Integer id;
    private String type;
    private String name;
    private String description;
}

Step 2: Write Dao layer interface

public interface BookDao {
    
    

    // 插入书籍
    @Insert("insert into tbl_book (type, name, description) values (#{type}, #{name}, #{description})")
    public void save(Book book);

    // 更新书籍
    @Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
    public void update(Book book);

    // 删除书籍
    @Delete("delete from tbl_book where id = #{id}")
    public void delete(Integer id);

    // 根据ID查询书籍
    @Select("select * from tbl_book where id = #{id}")
    public Book getById(Integer id);

    // 获取所有书籍
    @Select("select * from tbl_book")
    public List<Book> getAll();
}

illustrate:

  • These methods use the annotation method of MyBatis to specify the corresponding SQL statement, and associate the SQL statement with the method through @Insertthe , @Update, @Deleteand annotations. @SelectThe SQL statement in the annotation uses placeholders #{propertyName}to reference the attribute values ​​of the object to implement dynamic parameter binding.
  • Use these methods to conveniently perform database operations, such as inserting books, updating book information, deleting books, querying individual books, and getting a list of all books.

Step 3: Write the Service interface

@Transactional
public interface BookService {
    
    

    /**
     * 保存
     *
     * @param book
     * @return
     */
    public boolean saveBookInfo(Book book);

    /**
     * 修改
     *
     * @param book
     * @return
     */
    public boolean updateBookInfo(Book book);

    /**
     * 按id删除
     *
     * @param id
     * @return
     */
    public boolean deleteBookInfo(Integer id);

    /**
     * 按id查询
     *
     * @param id
     * @return
     */
    public Book getBookInfo(Integer id);

    /**
     * 查询全部
     *
     * @return
     */
    public List<Book> getBookAllInfo();
}

Notice:

  		当Spring使用了事务时,需要使用注解`@Transactional`来启用事务。若还需要对@Transactional做其余的配置,可以根据需求来进行决定

illustrate:

  • Generally speaking, when writing the Service interface layer, you need to know the name and meaning.
  • Generally speaking, when writing an interface, you need to return the operation results of this service

Step 4: Write the Service interface implementation layer

@Service
public class BookServiceImpl implements BookService {
    
    
    @Autowired
    private BookDao bookDao;

    public boolean save(Book book) {
    
    
        bookDao.save(book);
        return true;
    }

    public boolean update(Book book) {
    
    
        bookDao.update(book);
        return true;
    }

    public boolean delete(Integer id) {
    
    
        bookDao.delete(id);
        return true;
    }

    public Book getById(Integer id) {
    
    
        return bookDao.getById(id);
    }

    public List<Book> getAll() {
    
    
        return bookDao.getAll();
    }
}

illustrate:

Generally speaking, after writing the Service implementation class, you can test the methods of the Service layer.

Step 5: Test the Service layer

@RunWith(SpringJUnit4ClassRunner.class) // 注解指定了运行测试的类为SpringJUnit4ClassRunner,这样就能够在测试过程中启动Spring容器。
@ContextConfiguration(classes = SpringConfig.class) //注解指定了使用哪个配置类来加载Spring容器。
public class BookServiceTest {
    
    

    @Autowired
    private BookService bookService;

    @Test
    public void testGetById(){
    
    
        // 测试根据ID获取图书信息的方法
        Book book = bookService.getById(1);
        System.out.println(book);
    }

    @Test
    public void testGetAll(){
    
    
        // 测试获取所有图书信息的方法
        List<Book> all = bookService.getAll();
        System.out.println(all);
    }
}

Replenish:

  • @RunWithAnnotations are used to specify test runner (test runner), which tells JUnit to use a specific runner to execute the test when running the test.
  • @ContextConfigurationAnnotations are used to specify the configuration information of the Spring container and tell JUnit which configurations to load before running the test.

Step 6: Write the presentation layer

@RestController
@RequestMapping("/books")
public class BookController {
    
    

    @Autowired
    private BookService bookService;

    @PostMapping
    public boolean save(@RequestBody Book book) {
    
    
        return bookService.save(book);
    }

    @PutMapping
    public boolean update(@RequestBody Book book) {
    
    
        return bookService.update(book);
    }

    @DeleteMapping("/{id}")
    public boolean delete(@PathVariable Integer id) {
    
    
        return bookService.delete(id);
    }

    @GetMapping("/{id}")
    public Book getById(@PathVariable Integer id) {
    
    
        return bookService.getById(id);
    }

    @GetMapping
    public List<Book> getAll() {
    
    
        return bookService.getAll();
    }
}

6.4 Presentation layer data encapsulation

Summary of notes:

  • Overview: Data transfer and interaction between controller (Controller) and view (View).

  • Step 1: Set the return result class of unified data

    • The front-end receives the data format - creates the result model class and encapsulates the data into the data attribute
    • Front-end receiving data format - encapsulating special messages into the message (msg) attribute
    • The front end receives the data format - encapsulates the operation result into the code attribute
  • Step 2: Set the return status code of unified data

    //状态码
    public class Code {
           
           
        public static final Integer SAVE_OK = 20011;
        public static final Integer DELETE_OK = 20021;
    }
    
  • Step 3: Optimizing the Presentation Class

    • Unify the return value of each controller method

​ In the presentation layer (Presentation Layer), data encapsulation refers to the appropriate encapsulation and conversion of request data and response data to facilitate data transfer and interaction between the controller (Controller) and the view (View).

Step 1: Set the return result class of unified data

@Date
public class Result {
    
    
    //描述统一格式中的数据
    private Object data;
    //描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
    private Integer code;
    //描述统一格式中的消息,可选属性
    private String msg;

    public Result() {
    
    
    }

    public Result(Integer code,Object data) {
    
    
        this.data = data;
        this.code = code;
    }

    public Result(Integer code, Object data, String msg) {
    
    
        this.data = data;
        this.code = code;
        this.msg = msg;
    }
}

illustrate:

The fields in the Result class are not fixed and can be increased or decreased according to needs. Several construction methods are provided to facilitate operation.

  • The front-end receives the data format - creates the result model class and encapsulates the data into the data attribute
  • Front-end receiving data format - encapsulating special messages into the message (msg) attribute
  • The front end receives the data format - encapsulates the operation result into the code attribute

Step 2: Set the return status code of unified data

//状态码
public class Code {
    
    
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;
}

Step 3: Optimizing the Presentation Class

//统一每一个控制器方法返回值
@RestController
@RequestMapping("/books")
public class BookController {
    
    

    @Autowired
    private BookService bookService;

    @PostMapping
    public Result save(@RequestBody Book book) {
    
    
        boolean flag = bookService.save(book);
        return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
    }

    @PutMapping
    public Result update(@RequestBody Book book) {
    
    
        boolean flag = bookService.update(book);
        return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
    
    
        boolean flag = bookService.delete(id);
        return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
    }

    @GetMapping("/{id}")
    public Result getById(@PathVariable Integer id) {
    
    
        Book book = bookService.getById(id);
        Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
        String msg = book != null ? "" : "数据查询失败,请重试!";
        return new Result(code,book,msg);
    }

    @GetMapping
    public Result getAll() {
    
    
        List<Book> bookList = bookService.getAll();
        Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;
        String msg = bookList != null ? "" : "数据查询失败,请重试!";
        return new Result(code,bookList,msg);
    }
}

illustrate:

​ Generally speaking, business logic processing can be implemented in the presentation layer, where we can set the return processing of operation results.

6.5 Exception Handlers

Summary of notes:

  • Overview: Exception Handler is a mechanism for catching and handling exceptions that occur in an application .
  • Integration process:
    • Step 1: Create a new exception handling class
      • @RestControllerAdviceIs an annotation for global exception handling. It can catch and handle exceptions throughout the application and return the processing results to the client in a unified format
      • @ExceptionHandler(Exception.class)Annotations are used to identify an exception handling method and specify the type of exception to be caught and handled. Here, it catches Exceptionan exception of type.
  • Annotation explanation:
    • @RestControllerAdvice: is an annotation for global exception handling . Enhance controller classes developed in Rest style
    • @ExceptionHandler: Set the handling plan for the specified exception . The function is equivalent to the controller method. After an exception occurs, the original controller execution is terminated and transferred to the current method execution.

​Exception Handler is a mechanism for catching and handling exceptions that occur in applications. In Java web applications, exception handlers are usually used to capture exceptions that occur in the controller (Controller) and handle and respond appropriately as needed.

Common locations and common triggers for abnormal phenomena are as follows:

  • Exception thrown inside the framework: caused by illegal use
  • Exception thrown by the data layer: caused by external server failure (for example: server access timeout)
  • Exceptions thrown by the business layer: caused by business logic writing errors (for example: traversing business writing operations, resulting in index exceptions, etc.)
  • Exceptions thrown by the presentation layer: caused by data collection, verification and other rules (for example: exceptions caused by mismatched data types)
  • Exceptions thrown by tool classes: caused by loose writing of tool classes that are not robust enough (for example: connections that need to be released have not been released for a long time, etc.)

Step 1: Create a new exception handling class

Under the controller package, create a new ProjectExceptionAdvice class

@RestControllerAdvice
public class ProjectExceptionAdvice {
    
    

    /**
     * 全局异常处理方法
     * @param ex 异常对象
     * @return 自定义的结果对象
     */
    @ExceptionHandler(Exception.class)
    public Result doException(Exception ex){
    
    
        return new Result(666,null);
    }
}

illustrate:

  • @RestControllerAdviceIs an annotation for global exception handling. It can catch and handle exceptions throughout the application and return the processing results to the client in a unified format
  • @ExceptionHandler(Exception.class)Annotations are used to identify an exception handling method and specify the type of exception to be caught and handled. Here, it catches Exceptionexceptions of type .

Replenish:

  • Name:@RestControllerAdvice

    • Type: class annotation

    • Position: Above the controller enhancement class definition developed in Rest style

    • Function: Enhance controller classes developed in Rest style

    • example:

      @RestControllerAdvice
      public class ProjectExceptionAdvice {
               
               }
      
    • illustrate:

      • This annotation comes with @ResponseBody annotation and @Component annotation, which have corresponding functions.
  • Name:@ExceptionHandler

    • Type: method annotation

    • Location: Above the controller method dedicated to exception handling

    • Function: Set the handling plan for the specified exception . The function is equivalent to the controller method. After an exception occurs, the original controller execution is terminated and transferred to the current method execution.

    • example:

      @RestControllerAdvice
      public class ProjectExceptionAdvice {
               
               
          @ExceptionHandler(Exception.class)
          public Result doException(Exception ex){
               
               
              return new Result(666,null);
          }
      
    • This type of method can create multiple methods to handle the corresponding exceptions according to the different exceptions handled.

6.6 Project exception handling

Summary of notes:

  • Overview: Project exception handling refers to a mechanism to capture, handle and provide feedback on various abnormal situations during the development process .
  • Solution:
    • BusinessException: caused by irregular user operations
    • SystemException: Expected code operation exception
    • Other exceptions (Exception): Unexpected exceptions
  • Steps
    • Step 1: Customize project system-level exceptions
      • Inherit the RuntimeException runtime exception class
      • Implement the construction method according to the business, for example: SystemException(Integer code, String message), SystemException(Integer code, String message, Throwable cause)
    • Step 2: Customize project business-level exceptions
      • Inherit the RuntimeException runtime exception class
      • Implement the construction method according to the business, for example: BusinessException(Integer code, String message), BusinessException(Integer code, String message, Throwable cause)
    • Step 3: Customize exception coding (continuous addition)
    • Step 4: Start custom exception
    • Step 5: Intercept and handle exceptions (emphasis)
      • Define the project exception handling plan, and use @ExceptionHandlerthis annotation to handle exceptions

​ Project exception handling refers to a mechanism to capture, handle and provide feedback on various abnormal situations during the development process. The purpose of exception handling is to ensure the stability and reliability of the system to provide a good user experience.

Project exception handling plan

  • Business exception (BusinessException)
    • Send corresponding messages to users to remind them of standardized operations
  • System exception (SystemException)
    • Send a fixed message to the user to appease the user
    • Send specific messages to operation and maintenance personnel to remind maintenance
    • logging
  • Other exceptions (Exception)
    • Send a fixed message to the user to appease the user
    • Send specific messages to programmers to remind maintenance (included in expected range)
    • logging

Step 1: Customize project system-level exceptions

//自定义异常处理器,用于封装异常信息,对异常进行分类
public class SystemException extends RuntimeException{
    
    
    private Integer code;

    public Integer getCode() {
    
    
        return code;
    }

    public void setCode(Integer code) {
    
    
        this.code = code;
    }

    public SystemException(Integer code, String message) {
    
    
        super(message);
        this.code = code;
    }

    // Throwable为异常报错的对象
    public SystemException(Integer code, String message, Throwable cause) {
    
    
        super(message, cause);
        this.code = code;
    }
}

illustrate:

  • System-level exceptions may be caused by errors caused by programmers' errors.
  • For member variables code, you only need to implement the Set method of code. When using it later, you only need to obtain the Code of this object.

Step 2: Customize project business-level exceptions

//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{
    
    
    private Integer code;

    public Integer getCode() {
    
    
        return code;
    }

    public void setCode(Integer code) {
    
    
        this.code = code;
    }

    public BusinessException(Integer code, String message) {
    
    
        super(message);
        this.code = code;
    }

    // Throwable为异常报错的对象
    public BusinessException(Integer code, String message, Throwable cause) {
    
    
        super(message, cause);
        this.code = code;
    }
}

illustrate:

  • System-level exceptions may be caused by operating system problems or database connection failure.

Step 3: Customize exception coding (continuous addition)

public static final Integer SYSTEM_ERR = 50001;
public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
public static final Integer SYSTEM_UNKNOW_ERR = 59999;

public static final Integer BUSINESS_ERR = 60002;

Step 4: Trigger custom exception

image-20230531135942393

illustrate:

​ Through simulation, only the classification and throwing of exceptions

Step 5: Intercept and handle exceptions

//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    
    
    // 用于处理用户操作不当而导致的异常
    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
    
    
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
    
    
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
    
    
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

Step 6: Comparison of exception handler effects

image-20230531140236636

illustrate:

It can be seen that the software system can make accurate prompts when resource access is normal or abnormal.

7. Interceptor

Summary of notes:

  1. Overview:
  • Definition: Interceptor is a technology commonly used in web development, which is used to intercept and process requests during request processing.

  • Function: Execute preset code before and after calling the specified method and prevent the execution of the original method

  • The difference between interceptors and filters:

    • Different belongings
    • Block content is different
    • ……

    image-20230814122356401

  1. Basic use case:
  • Step 1: Declare the interceptor bean and implement the HandlerInterceptor interface (note: scan and load beans)
  • Step 2: Define the configuration class
    • Method 1: Define the configuration class, inherit WebMvcConfigurationSupport , and implement the addInterceptor method (note: scan to load the configuration)
    • Method 2: Implement the standard interface webMvcConfigurer to simplify development (note: more intrusive)
  • Replenish:
    • Configure static resource mapping: addResourceHandlers, addResourceLocations
    • Configure interceptors for dynamic resources: addInterceptors, addPathPatterns
  1. Interceptor parameters:
  • Pre-processing: some processing done before request interception
  • Post-processing: some processing done after request interception
  1. Interceptor workflow:
  • Interceptors: single interceptor processing

    image-20230531144547904

  • Intercept chain: multiple interceptor processing

    image-20230531154459978

7.1 Overview

7.1.1 Definition

​Interceptor is a technology commonly used in web development, which is used to intercept and process requests during request processing. The interceptor can perform some custom logic before or after the request enters the controller for processing, such as logging, permission verification, request parameter preprocessing, etc.

image-20230603105043433

7.1.2 Function

Execute preset code before and after the specified method call and prevent the execution of the original method. The functions are as follows:

  1. Permission verification: Interceptors can be used to verify user permissions, such as checking whether the user is logged in, has the permission to perform an operation, etc. If permission verification fails, you can interrupt the request or perform corresponding processing.
  2. Logging: The interceptor can be used to record the log information of the request, including the requested URL, request parameters, request time, etc., to facilitate subsequent statistical analysis, error troubleshooting and other work.
  3. Request parameter preprocessing: The interceptor can preprocess the request parameters before the request enters the controller, such as verifying, formatting, and encrypting the parameters to ensure the correctness and security of the parameters.
  4. Exception handling: Interceptors can be used to capture exceptions thrown in the controller and perform unified exception handling, such as returning a unified error message page, recording exception logs, etc.
  5. Request response processing: The interceptor can process the response after the request processing is completed, such as setting response header information, modifying response content, etc.
  6. Cache control: Interceptors can be used to control the caching strategy of the response, such as setting the cache time of the response, verifying the validity of the cache, etc.

Normally, in actual development, interceptors are usually used for Token permissions

7.1.3 Difference between interceptor and filter

Interceptor and Filter are both components used to process requests in web development, but they have the following differences:

  1. The application scope is different: the interceptor is for the Spring MVC framework . It is method-based interception and can only intercept the request processing method in the controller. The filter is defined by the Servlet specification. It is based on URL pattern interception and can intercept all requests, including static resources and Servlet requests.

  2. The order of execution is different: the interceptor is executed before or after the processor (Controller), and can pre-process or post-process the request. Filters are executed before or after the request enters the Servlet container, and can filter, modify or package the request.

  3. Different functions : Interceptors are mainly used to process the business logic of requests , such as permission verification, logging, exception handling, etc. Filters are mainly used to filter and modify requests , such as character encoding conversion, request packaging, request parameter processing, etc.

  4. The configuration methods are different: the interceptor configuration is performed in the Spring MVC configuration file, and the order and path matching rules of the interceptors need to be manually configured. The filter configuration is performed in the web.xml file, and the interception path and order of the filter are specified by configuring the URL pattern.

  5. Different ownership : Filter belongs to Servlet technology , Interceptor belongs to SpringMVC technology

  6. The interception content is different: Filter enhances all access , and Interceptor only enhances springMVC access.

image-20230603105732011

​ Generally speaking, interceptors are more flexible and refined, suitable for processing business logic; filters are more general, suitable for filtering and modifying requests. When using it, you can select interceptors or filters according to specific needs to implement the corresponding functions.

7.2 Basic use case-interceptor implementation

Step 1: Define the interceptor

  • Declare the interceptor Bean and implement the HandlerInterceptor interface

Notice:

Scan and load beans, remember to add @Componentannotations

@Component //拦截器
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    
    
    @Override
    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("preHandle..."+contentType);
        return true;
    }

    @Override
    //原始方法调用后执行的内容
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("postHandle...");
    }

    @Override
    //原始方法调用完成后执行的内容
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("afterCompletion...");
    }
}

illustrate:

Generally speaking, interceptors are used for presentation layer processing, so the interceptors are placed under the Controller package.

Step 2: Define the configuration class

Method 1: Define the configuration class, inherit WebMvcConfigurationSupport, and implement the addInterceptor method (note: scan to load the configuration)

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    
    
    @Autowired
    private ProjectInterceptor projectInterceptor;

    /**
     * 配置静态资源映射
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    /**
     * 配置动态资源的拦截器
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }
}

illustrate:

  • Through the above configuration, access to static resources and interceptor configuration for the specified path are achieved.
  • Add an interceptor and set the intercepted access path. Multiple paths can be set through variable parameters.

Method 2: Implement standard interfaces webMvcConfigurerto simplify development (note: more intrusive)

@Configuration
@ComponentScan({
    
    "com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
    
    
    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        //配置多拦截器
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }
}

illustrate:

By implementing the WebMvcConfigurer interface, you can also achieve the effect of inheriting the WebMvcConfigurationSupport configuration class to implement resource interception.

Notice:

​ Implementing the interceptor by implementing the WebMvcConfigurer interface is highly intrusive.

7.3 Interceptor parameters

7.3.1 Preprocessing

Pre-processing is some processing done before request interception

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    
    
    @Override
    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        String contentType = request.getHeader("Content-Type");
        HandlerMethod hm = (HandlerMethod)handler;
        System.out.println("preHandle..."+contentType);
        return true;
    }
}

illustrate:

​ The information in the request header can be obtained from the request, and can be taken out for easy operation.

Replenish:

  • parameter:
    • request: request object
    • response: response object
    • handler: The called handler object is essentially a method object, which repackages the Method object in reflection technology.
  • return value
    • The return value is false, and the intercepted processor will not be executed.

7.3.2 Post-processing

public void postHandle(HttpServletRequest request,
                       HttpservletResponse response,
                       object handler,
                       ModelAndview modelAndView) throws Exception {
    
    
    System.out.println( "postHandle..." );
}

Replenish:

modelAndView: If the processor execution is completed and the result is returned, the corresponding data and page information can be read and adjusted.

7.4 Interceptor workflow (key points)

7.4.1Basic process

image-20230531144547904

illustrate:

  • When there is no interceptor, the request passes through the presentation layer without any interception.
  • When there is an interceptor, the request will be interpreted as intercepting and processing the content executed before the original method is called, the content executed after the original method is called, and the content executed after the original method is called.
  • If the response is True after interception processing, it means that the request is released; if the response is False, it means that the request content is intercepted.

7.4.2 Interception chain

image-20230531154459978

illustrate:

  • If the third interceptor returns False, only the post-processors of the first and second interceptions will be run.
  • If the second interceptor returns False, only the post-processor of the first interception will be run.
  • If the first interceptor returns False, none of the intercepted post-processors will run.

8. Execution process

Summary of notes:

​ This section is more complicated, we can refer to external notes for study: springmvc notes (Silicon Valley)_blog that doesn’t know how to type 314-CSDN blog

8.1 Common components of SpringMVC

  • DispatcherServlet : DispatcherServlet is the front-end controller of the Spring MVC framework . It is responsible for receiving all HTTP requests and distributing the requests to the corresponding processor for processing. DispatcherServlet is the core component of the Spring MVC framework, which dispatches all aspects of the request processing process.
  • HandlerMapping : HandlerMapping is an implementation of the processor mapper. It maps to a specific processor (Controller) according to the requested URL path and determines the processor corresponding to the request . HandlerMapping can be configured according to different mapping strategies, such as based on URL paths, based on annotations, etc.
  • Handler : Handler means processor , also called Controller . It is the specific executor of business logic, responsible for processing requests and returning processing results. In Spring MVC, Handler can be an ordinary POJO class that handles requests through methods.
  • HandlerAdapter : HandlerAdapter is a processor adapter that is used to execute processor methods and adapt the request parameters so that it can correctly handle the request. HandlerAdapter selects the appropriate adapter to execute the processor method based on the type of processor and the parameter type of the processing method.
  • ViewResolver : ViewResolver is a view resolver that renders the processing results into the final view. It parses out specific view objects based on the logical view name returned by the processor, such as ThymeleafView, InternalResourceView, RedirectView, etc. ViewResolver is responsible for passing model data to the view and ultimately presenting it to the user.
  • View : View means view , which is responsible for displaying the final processing results to the user. Views can be HTML pages, JSON data, XML documents, etc. In Spring MVC, views are usually rendered through a template engine, and model data is filled into the template to generate the final view.

image-20230602102312053

​ 这些组件共同协作,完成请求的处理和响应的生成。DispatcherServlet作为前端控制器接收请求,HandlerMapping确定请求对应的处理器,HandlerAdapter执行处理器方法,ViewResolver解析视图,View负责最终的呈现。这个处理流程是Spring MVC框架中的核心机制,通过配置和组合这些组件,可以灵活地实现不同的请求处理和视图渲染逻辑。

8.2DispatcherServlet初始化过程

​ DispatcherServlet 本质上是一个 Servlet,所以天然的遵循 Servlet 的生命周期。所以宏观上是 Servlet 生命周期来进行调度

image-20230602094211246

说明:

1.GenericServlet类会实现Service接口并重写Init方法

image-20230602112204665

说明:

  • 因为Servler为接口,因此GenericServlet类会实现Service接口并重写Init方法
  • 因为HttpServlet类跟GenericSerlver为继承的关系,因此GenericServlet类中的两个init方法,会保留在HttpServlet类中

2.HttpServlet类没有重写GenericServlet类中的init方法

image-20230602112719365

说明:

​ HttpServlet类虽然继承了GenericServlet类,但并没有重写GenericServlet类中的init方法

3.HttpServletBean类重写了GenericServlet类中的init方法,并调用了initServletBean方法

image-20230602112804189

说明:

​ HttpServletBean类重写了GenericServlet类中的init方法

image-20230602113308369

说明:

​ HttpServletBean类在init方法中,调用了一个重要的方法initServletBean方法,来初始化ServletBean

4.FrameworkServler类重写了HttpServletBean类中的initServletBean方法

image-20230602113741285

说明:

The FrameworkServler class calls the SpringMVC IOC container initialization method this.initWebApplicationContext(); in the initServletBean method;

5. In the FrameworkServler class, the initWebApplicationContext method will be called

image-20230602114621108

illustrate:

​ Because when this method is executed for the first time, the created WebApplicationContext is empty, so this.createWebApplicationContext(rootContext); this method will be called to create the WebApplicationContext.

5.1. In the FrameworkServler class, call the createWebApplicationContext method to create a WebApplicationContext

image-20230602114841908

image-20230602191454335

illustrate:

​ Call the wac.setParent(parent); method in the FrameworkServler class to set the Spring IOC container as the parent container of Spring MVC

5.2 In the FrameworkServler class, call this.onRefresh(wac) and this.getServletContext().setAttribute(attrName, wac); methods

image-20230602192539137

illustrate:

  • Calling this.onRefresh(wac) method will execute the OnRefresh method in the subclass DispatcherServlet class to initialize the strategy.

    image-20230602193255953

  • Call this.getServletContext().setAttribute(attrName, wac); method to share the webApplicationContext object in the application domain

6. In the DispatcherServler class, the onRefresh method in the FrameworkServler class will be overridden.

image-20230602193437015

image-20230602193510752

illustrate:

​ The various containers initialized inside are actually loaded when DispatcherServlet is initialized.

8.3DispatcherServlet service process

1. The GenericServlet class will implement the Service interface and inherit this Service method.

image-20230602194934369

illustrate:

In the GenericServlet class, the service method in the Service interface is not overridden, but directly inherited.

2. In the HttpServlet class, the Service method in the GenericServlet class is rewritten.

image-20230602195300896

illustrate:

​ In the Service method of the HttpServlet class, convert the ServletRequest and ServletResponse objects into subclasses HttpServletRequest and HttpServletRequest, and HttpServletResponse objects.

3. In the service method in the HttpServlet class, distribute the request

image-20230602195750111

illustrate:

​ Different methods execute corresponding to different functions

4. In HttpServletBean, the service method in the HttpServlet class and the method starting with do are not rewritten.

image-20230602195928441

illustrate:

In the HttpServlet class, the service method in the HttpServlet class and the method starting with do are not rewritten.

5. In the FramesServlet class, the this.processRequest method of this class will be executed anyway

image-20230602200359274

illustrate:

The super.service(request,response) method will execute the service method in HttpServlet, not the HttpServiceBean class, because the HttpServiceBean class does not implement any service method.

image-20230602200529945

illustrate:

An important method doService is implemented in the processRequest method in the FramesServlet class

image-20230602200606022

illustrate:

​ In the doService method in the FramesServlet class, it is found that doService is an abstract class method. Therefore, we need to see how to implement this method in a subclass of the FramesServlet class

6. In the DispatcherServlet class, the this.doDispatch(request, response); method will eventually be executed to process the service.

image-20230602201202436

8.4The process of DisPatcheServlet calling component to process the request

1. In the DispatcherServlet class, assign values ​​to the processing execution chain through mappedHandler = this.getHandler(processedRequest);

image-20230603100700034

illustrate:

  • In line 472 HandlerExecutionChain mappedHandler = null;, mappedHandler is called the execution chain, including controller methods (processors), interceptor collections, and interceptor indexes.

    image-20230603101356041

image-20230603101506491

illustrate:

  • HandlerAdapter is used to call methods of the controller

    image-20230603101557702

image-20230603101946004

illustrate:

The ha.handle method is used in the adapter to process the parameter types, request headers, and request cookies of the request method.

image-20230603102443189

illustrate:

It can be found that in the doDispatch method in the DispatcherServler class, there is no method to render the view. In fact, the this.processDispatchResult method is a method used to process subsequent steps. In this method, the view will be subsequently processed.

8.5 Execution process (understanding)

To be added……

Knowledge Gas Station (Key Points)

1.The difference between @RequestBody and @RequestParam

  • the difference
    • @RequestParam is used to receive url address parameters and form parameters [application/x-www-form-urlencoded]
    • @RequestBody is used to receive json data [application/json]
  • application
    • In the later stage of development, the data in json format is mainly sent, and @RequestBody is widely used
    • If you send data in non-json format, use @RequestParam to receive request parameters

2. In Idea, open the class relationship inheritance diagram

Shortcut key: Ctrl+H

image-20230530141253472

3. The difference between @RequestBody @RequestParam @PathVariable

  • the difference
    • @RequestParam is used to receive url address or form parameters
    • @RequestBody is used to receive json data
    • @PathVariable is used to receive path parameters, use {parameter name} to describe the path parameters
  • application
    • In the later stage of development, when sending more than one request parameter, the json format is the main format, and @RequestBody is widely used
    • If you send data in non-json format, use @RequestParam to receive request parameters
    • Use RESTful for development. When the number of parameters is small, such as 1, you can use @PathVariable to receive the request path variable, which is usually used to pass the id value.

4. The difference between @RestControllerAdvice and @ControllerAdvice

@RestControllerAdviceand @ControllerAdviceare annotations for global exception handling and global data binding in Spring MVC. Their differences are as follows:

  1. @RestControllerAdviceIs a combined annotation of @ControllerAdviceand @ResponseBody, representing a controller enhancer for global exception handling and global data binding, and returning the results to the client in JSON format.
  2. @ControllerAdviceis a controller enhancer for global exception handling and global data binding, which can be applied to all controller classes annotated with @Controlleror .@RestController
  3. Classes using annotations can use , and annotations @RestControllerAdviceon methods to implement global exception handling, data binding and preprocessing.@ExceptionHandler@InitBinder@ModelAttribute
  4. Classes using annotations can use , and annotations @ControllerAdviceon methods to implement global exception handling, data binding and preprocessing. But the returned results need to be converted to JSON format through annotations or other methods.@ExceptionHandler@InitBinder@ModelAttribute@ResponseBody

To summarize, the main difference is the format of the returned results. @RestControllerAdviceThe results returned by the annotated class will be returned directly to the client in JSON format, while @ControllerAdvicethe annotated class needs to use @ResponseBodyannotations or other methods to convert the results into JSON format and return it to the client.

5. SpringMVC supports ant-style paths

? : represents any single character

*: represents any 0 or more characters

**: Indicates any one or more levels of directories

Note: When using , you can only use // xxx method

6.The relationship between Model, Map, ModelMap and ModelAndView

image-20230601084245953

7.AbstractAnnotationConfigDispatcherServletInitializer 和 AbstractDispatcherServletInitializer 类区别

AbstractAnnotationConfigDispatcherServletInitializerand AbstractDispatcherServletInitializerare abstract classes in Spring MVC used to configure and initialize DispatcherServlet.

  1. AbstractAnnotationConfigDispatcherServletInitializer:
    • AbstractAnnotationConfigDispatcherServletInitializerIs an abstract class, inherited from AbstractDispatcherServletInitializer.
    • This class is used to configure and initialize DispatcherServlet based on Java configuration.
    • By inheriting this class and implementing its abstract methods, you can configure RootConfig and ServletConfig related classes, as well as Servlet mapping paths, etc.
    • It is used AnnotationConfigWebApplicationContextto load the configuration class and associate it with the DispatcherServlet.
  2. AbstractDispatcherServletInitializer:
    • AbstractDispatcherServletInitializerIt is an abstract class and WebApplicationInitializerthe implementation class of the interface.
    • This class is used to configure and initialize DispatcherServlet based on traditional XML configuration.
    • It can be used to create and register DispatcherServlet, and configure Servlet mapping path, etc.
    • By inheriting this class and implementing the abstract methods in it, you can configure the relevant XML configuration file paths of RootConfig and ServletConfig.

Summary: AbstractAnnotationConfigDispatcherServletInitializerThe abstract class of DispatcherServlet is configured and initialized based on Java configuration, AbstractDispatcherServletInitializerbut abstract class of DispatcherServlet is configured and initialized based on traditional XML configuration. They provide different ways to configure and initialize DispatcherServlet, allowing developers to choose the appropriate method according to their preferences and project needs.

8. @RequestHeader annotation (emphasis)

@RequestHeaderAnnotations are used to bind values ​​in request headers to method parameters. It can be used to get the value of a specific request header, or to get the value of all request headers. This annotation can be applied to method parameters, methods, and class-level handler methods.

  • Get the value of a specific request header
@GetMapping("/example")
public void exampleMethod(@RequestHeader("User-Agent") String userAgent) {
    
    
    // 处理方法逻辑
}
  • Get the values ​​of all request headers
@GetMapping("/init2")
public void init2(@RequestHeader Map<String, String> headerMap) {
    
    
    
    // 使用Map接收所有的请求头
    System.out.println(headerMap);
    // js中使用header名为addressList,使用map接收后需要使用addresslist
    System.out.println(headerMap.get("addresslist"));  
    
}

9. @CookieValue annotation (emphasis)

@CookieValueAnnotations are used to bind values ​​in cookies to method parameters. It can be used to get the value of a specific cookie, or to get the value of all cookies. This annotation can be applied to method parameters, methods, and class-level handler methods.

  • Get the value of a specific request header
@GetMapping("/example")
public void exampleMethod(@CookieValue("sessionId") String sessionId) {
    
    
    // 处理方法逻辑
}
  • Get the values ​​of all request headers
@GetMapping("/example")
public void exampleMethod(@CookieValue Map<String, String> cookies) {
    
    
    // 处理方法逻辑
    for (Map.Entry<String, String> entry : cookies.entrySet()) {
    
    
        String cookieName = entry.getKey();
        String cookieValue = entry.getValue();
        // 处理每个Cookie的逻辑
    }
}

10. HttpServlet container responds to Web client request process

1) The web client issues an Http request to the Servlet container;

2) The Servlet container parses the Http request of the Web client;

3) The Servlet container creates an HttpRequest object and encapsulates the Http request information in this object;

4) The Servlet container creates an HttpResponse object;

5) The Servlet container calls the service method of HttpServlet. In this method, it will be determined whether to execute doGet or doPost based on the Method of the request, and the HttpRequest and HttpResponse objects are passed to the HttpServlet object as parameters of the service method;

6) HttpServlet calls the relevant methods of HttpRequest to obtain HTTP request information;

7) HttpServlet calls the relevant methods of HttpResponse to generate response data;

8) The Servlet container passes the response result of HttpServlet to the Web client.

Guess you like

Origin blog.csdn.net/D_boj/article/details/132287050