Spring MVC notes - and SSM integration ideas

SpringMVC

Translation of Chinese documents: https://github.com/DocsHome/spring-docs/blob/master/pages/web/overview.md

Search GitHub for spring docs

Introduction to Spring MVC

Spring MVC is a part of spring framework. It is a lightweight web framework based on Java implementation.

The core of spring MVC

The core of learning Spring MVC framework is the design of central scheduler (Dispatcher Servlet). Mastering Dispatcher Servlet is the core key to mastering Spring MVC.

Spring MVC is a management controller object. Before spring MVC, Servlet was used as a controller object. Now create an object called controller through the spring MVC container to perform the role and function of controller instead of Servlet.

Import dependency

Note: in Tomcat 10 After X, the point to import is not the previous javax Servlet API. Instead, you need to replace it with the following dependencies. The web uses Jakarta Servlet dependency.

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>5.0.0</version>
    <scope>provided</scope>
</dependency>
<!--    springmvc rely on-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.5</version>
        </dependency>

Configuration of central scheduler

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--to configure springmvc central scheduler -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--spring Profile location-->
        <!--
        The default configuration file is /WEB-INF/springmvc-servlet.xml  If you do not configure the file path, you will find the file in this place by default
                The default name of the file is what we configured DispatcherServlet(The name of the central scheduler) plus -servlet.xml form  <servlet-name>-servlet.xml
                springmvc If the configuration file is not configured, it is loaded every time the configured virtual mapping path is accessed,
                WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc-servlet.xml");
                establish web Container object ctx You need to read the configuration file. This configuration file and Spring The configuration of the configuration file is consistent
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <!--web Load on container startup,The configuration file is loaded only once-->
        <!--
            web container Tomcat The sequence of creating containers. The smaller the value, the earlier the creation time (integer value greater than 0) (greater than 0 means it will be created when starting), and the value 0 means it will be created when accessing
        -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--Intercept (capture) except jsp All requests other than documents-->
        <!--
        Give some requests to servlet Processing
        Common formats of central scheduler:
        1. Use extension name   *.xx  xx Is a custom extension name  *.do *.test
            But note: it cannot be used *.jsp Because jsp Do you want to access this page view or do you want to end with jsp The final request is handled by the central scheduler, which is ambiguous
        2. use / It will be introduced later
        -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
<!--Annotation scanner-->
    <context:component-scan base-package="com.mao.web.controller"/>
<!--View parser to help parse views-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--Prefix that specifies the path to the view file-->
        <property name="prefix" value="/WEB-INF/view/"/>
<!--Suffix that specifies the extended name of the view file-->
        <property name="suffix" value=".jsp"/>
    </bean>
package com.mao.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Description
 * @Author Hairy
 * @CreateDate 2021/06/01/Tuesday 1:48 PM
 */
@Controller
public class HelloMVC {
    // RequestMapping annotation,
    // Location: it can be placed on the method or on the class (optional)
    // Attribute: value is an array that can contain multiple request lists, that is, a method can process multiple requests. The value of the array must be unique, starting with /
    // Function: submit the specified request to the specified method for processing, which is equivalent to URL pattern
    @RequestMapping(value= {"/some.do"})
    public ModelAndView hello(){
        ModelAndView mv = new ModelAndView();
        // Add an object to the request field, which is equivalent to request setAttribute("","")
        mv.addObject("username","mao");
        // Specify the view, and the parameter is the full path of the view
        // However, after the view parser is configured (configured in the configuration file), the parameter is the logical name of the view
        // The logical name is used. The framework uses the prefix and suffix of the view parser in the configuration file to splice into a complete path
        // Request forwarding operation performed by the view...
        mv.setViewName("hello");
        return mv;
    }

    /**
     * Visit other Do, request forwarding to other page
     * @return
     */
    @RequestMapping(value= {"/test/other.do"})
    public ModelAndView doOther(){
        ModelAndView mv = new ModelAndView();
        // Add an object to the request field, which is equivalent to request setAttribute("","")
        mv.addObject("username","other");
        mv.setViewName("other");
        return mv;
    }
}

Processing of requests

General conditions:

User initiated request - "Tomcat received request." DispatcherServlet - dispatch - controller of specific execution - returns the processing result

MVC components of spring MVC

2. Spring MVC annotated development

2.1 use of @ requestmapping annotation

Attribute: url address of value request (virtual mapping)

Location: 1 On the method, the required attribute is 2 Above the class as the module name

The attribute method is the method of the request. The enumeration value of the RequestMethod class is used to represent the method of the request.

2.1.1 specify module name
// RequestMapping annotation,
// Location: it can be placed on the method or on the class (optional)
// Attribute: value is an array that can contain multiple request lists, that is, a method can process multiple requests. The value of the array must be unique, starting with /
// Function: submit the specified request to the specified method for processing, which is equivalent to URL pattern
@RequestMapping(value={"/some.do"})
@Controller
@RequestMapping(value = "/test") // value attribute: indicates the public prefix of all request addresses, which is equivalent to the module name and is located above the class declaration
public class MyController {
    // Both request addresses have / test prefix, so they can be extracted
//    @RequestMapping(value = {"/test/some.do"})
    @RequestMapping(value = {"/some.do"})
    public ModelAndView doSome() {
        ModelAndView mv = new ModelAndView();
        mv.addObject("username", "mao");
        mv.setViewName("hello");
        return mv;
    }

    //    @RequestMapping(value = {"/test/other.do"})
    @RequestMapping(value = {"/other.do"})
    public ModelAndView doOther() {
        ModelAndView mv = new ModelAndView();
        mv.addObject("username", "jun");
        mv.setViewName("other");
        return mv;
    }
}
2.1.2 definition of request submission method

The annotation @ RequestMapping has the attribute method, which is used to limit the submission method of the request processed by the annotation method, that is, only the request that meets the submission method specified by the method attribute will execute the annotation method.

The value of the method attribute is the RequestMethod enumeration constant. The common is RequestMethod Get and RequestMethod Post mode.

If this attribute is not specified, the request mode is arbitrary and any request can be made. The request can be processed in all ways.

/**
 * @RequestMapping: Attribute method: request method: use the constant of the RequestMethod enumeration class for assignment. If this attribute is not specified, the request method is arbitrary and any request can be made
 * @return
 */
@RequestMapping(value = {"/show.do"},method = RequestMethod.GET)
public ModelAndView doShow() {
    ModelAndView mv = new ModelAndView();
    mv.addObject("username", "jun");
    mv.setViewName("other");
    return mv;
}
2.1.3 parameters of processor method

Parameters can contain four types. These parameters will be automatically assigned by the system during system call. It is good for programmers to call directly inside the method.

  1. HttpServletRequest
  2. HttpServletResponse
  3. httpSession
  4. Parameters carried in the request
    @RequestMapping(value = {"/request.do"},method = RequestMethod.GET)
    public ModelAndView doRequest(HttpServletRequest request, HttpServletResponse response) {
        ModelAndView mv = new ModelAndView();
        // Get the request parameters and use the request object to get them
        System.out.println(request.getRequestURI());
        mv.addObject("username", request.getParameter("username"));
        mv.setViewName("post");
        return mv;
    }
2.1.4 parameters of receiving request

Error: status code 400 indicates client exception. It mainly occurs in the process of user submitting parameters.

1. Receive parameters one by one

As long as the request parameter name is the same as that of the request processing method.

  1. It is best to use the packaging type for the reception of parameters. For example, Integer, etc. It can receive null values and other situations. It receives null

  2. The framework can use automatic conversion from String to int, float and other types.

  3. If there is a problem of garbled code in the post request, use the character set filter

/**
     * Receive the request parameter by name. The request parameter name is the same as the row parameter name of the controller method name. Receive request parameters by name object mapping
     * @param username user name
     * @param password password
     * @param age age Must be a number
     *            Parameter receiving: the framework uses the request object to receive parameters
     *                 String username = request.getParameter("");
     *            When the doProperParam method is called inside the central scheduler, the parameters are passed by name object
     *                 doProperParam(username,password,Integer.valueOf(age))
     *                 The framework can realize the conversion of request parameters from String to int, long, float and other types.
     *            If the parameter passed by the client is null or the field is not assigned, it is recommended that the receiving parameter type of the method use the wrapper class to receive the null parameter Integer
     *            
     * @return
     */
    @RequestMapping(value = {"/param.do"})
    public ModelAndView doParam(String username,String password,Integer age) {
        ModelAndView mv = new ModelAndView();
        // Get the request parameters and use the request object to get them
        mv.addObject("username", username);
        mv.addObject("password", password);
        mv.addObject("age", age);
        mv.setViewName("param");
        return mv;
    }

Spring MVC filter to solve the problem of Chinese garbled code

Spring MVC provides a good filter to solve garbled code by default. Charaverterencodingfilter class

    <!--Declaration framework provides good filters: provided by the framework, solve post Request Chinese garbled code problem-->
    <filter>
        <filter-name>filter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--Assign a value to the attribute of the filter-->
        <init-param>
<!--Character set used by the project-->
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
<!--            Mandatory request object( request)Object use encoding Coding format of-->
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
<!--            Force response object usage encoding Coding format of-->
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
<!--Force all requests to go through the filter first-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
Request parameter name and row parameter name are inconsistent (@ RequestParam)

Use @ RequestParam annotation to solve the inconsistency of parameter names

/**
     * Request parameters and row parameters are inconsistent
     *      When the request parameter name is inconsistent with the row parameter name, we use the @ RequestParam annotation to solve it
     *      Attribute: value: the name of the current parameter in the request
     *             required: boolean Type. The default is true
     *             Indicates that this parameter must be present in the request. If it is absent, an error will be reported. Having this parameter does not mean that the parameter must have a value, but the parameter must be passed
     *      Position: before row parameter definition
     * @param name
     * @param password
     * @param age
     * @return
     */
    @RequestMapping(value = {"/param2.do"})
    public ModelAndView doParam2(@RequestParam("name") String name,@RequestParam("pwd") String password,@RequestParam("age") Integer age) {
        ModelAndView mv = new ModelAndView();
        // Get the request parameters and use the request object to get them
        mv.addObject("username", name);
        mv.addObject("password", password);
        mv.addObject("age", age);
        mv.setViewName("param");
        return mv;
    }
}
2. Object reception

When there are multiple request parameters, it is recommended to receive them in the form of objects.

Object receiving: the row parameter of the controller method is a java object, and the attribute of the java object is used to receive the request parameter value.

Requirement: the attribute name of the Java object is the same as the parameter name in the request. (this is the simplest way)

/**
 * Use the object to receive the parameters in the request,
 * Requirement: the request parameter name here is consistent with the attribute name of the object
 *      java Class has a parameterless constructor and property has a set method
 *  Frame handling:
 *      1.  Call the parameterless construction method of user to create the object
 *      2.  Call the set method of the object, and call the corresponding set method for the parameter with the same name
 *      If the parameter is username, call the set method of the attribute username
 * @return
 */
@RequestMapping(value = {"/obj.do"})
public ModelAndView doObj(User user) {
    ModelAndView mv = new ModelAndView();
    // Get the request parameters and use the request object to get them
    mv.addObject("username", user.getUsername());
    mv.addObject("password", user.getPassword());
    mv.addObject("age", user.getAge());
    mv.setViewName("obj");
    return mv;
}

package com.mao.bean;

/**
 * @Description
 * @Author Hairy
 * @CreateDate 2021/06/03/Thursday 11:27 am
 */
public class User {
    private String username;
    private String password;
    private Integer age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

2.2 role of dispatcher Servlet

  1. Create the container object of spring MVC in init(). WebApplicationContext wcp = new ClassPathXmlApplicationContext();

Create all java objects in the spring MVC configuration file. A java object is a controller object

  1. DispatcherServlet itself is a servlet, but it is not written by us. It is responsible for receiving requests.

2.3 description of configuration file

  1. web.xml deployment descriptor file. It is for the server (Tomcat). The function of the file is that when Tomcat starts, Tomcat reads the web XML file, create various objects according to the declaration of the file, and know the mapping relationship between requests and servlet and other objects according to the declaration in the file.
  2. The configuration file of the framework. Spring MVC configuration file. Function: the declaration framework creates various objects in the project, mainly creating Controller objects.
Sequence and function of loading configuration files
  1. Start the tomcat server and read the web XML and create objects according to the description of the file.

    <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
    				<!---->
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    

    When the dispatcher servlet class object is created, the init() method will be executed. Spring MVC container object creation is performed in the init method

    WebApplicationContext ctx = new ClassPathApplicationContext('"classpath:springmvc.xml");

  2. When spring MVC reads the configuration file,

    <!--Annotation scanner-->
        <context:component-scan base-package="com.mao.web.controller"/>
    <!--View parser to help parse views-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--Prefix that specifies the path to the view file-->
            <property name="prefix" value="/WEB-INF/view/"/>
    <!--Suffix that specifies the extended name of the view file-->
            <property name="suffix" value=".jsp"/>
        </bean>
    

    Use the component scanner to traverse all classes in the Controller package, find the annotation @ Controller and annotation @ RequestMapping declared on the class, and then create the corresponding object. You know that the request is to execute the method to process the request.

  3. User initiated request ---- "central scheduler ----"

    There is a WebApplicationContext in the central scheduler and a controller object in the WebApplicationContext. The central scheduler knows which execution method the request is.

2.4 return value of controller method

The return value of the controller method represents the processing result of this request. The return values include ModelAndView, String, void and Object. Four categories

The processing result of the request includes: data and view.

2.4.1 ModelAndView data and views

The response result of the request has data and view, and ModelAndView is the most convenient

Data: stored in the request scope

View: performing request forwarding operations

2.4.2 String view

The return value of the controller method is String, which means forward forwarding operation is performed. The result of the response is a view.

A view can be a complete view path or a logical name of the view.

At present, the conflict between view parser and full view path has not been solved.

/**
     * The controller method returns a String representing the name of the logical view. The view parser needs to be configured in the project
     *
     * @return
     */
    @RequestMapping(value = {"/returnString.do"})
    public String doReturnString(HttpServletRequest request, String username, String password) {
        System.out.println(username);
        System.out.println(password);
        // You need to handle the request data manually
        // Add the HttpServletRequest parameter to the row parameter
        request.setAttribute("username", username);
        request.setAttribute("password", password);
        // Forward the request to return / returnstring JSP page
        return "return/returnString";
    }

    /**
     * Full view path, view parser cannot be configured in the project
     *
     * @param request
     * @param username
     * @param password
     * @return
     */
    @RequestMapping(value = {"/returnString2.do"})
    public String doReturnString2(HttpServletRequest request, String username, String password) {
        System.out.println(username);
        System.out.println(password);
        // You need to handle the request data manually
        // Add the HttpServletRequest parameter to the row parameter
        request.setAttribute("username", username);
        request.setAttribute("password", password);
        // Forward the request to return / returnstring JSP page
        // There is a view parser currently configured. If you write a complete path, you will certainly report an error. Therefore, the full path conflicts with the view parser, which can be solved later
        return "return/returnString";
    }
}
2.4.3 no data and views

The null return value void is often used in response to ajax requests. Use the response object HttpServletResponse object to output data in response to ajax requests.

/**
 * The controller method returns void, responds to the ajax request, and uses HttpServletResponse to output data
 * @param name
 * @param age
 */
@RequestMapping("/returnVoid-ajax.do")
public void doAjax(HttpServletResponse response,String name, Integer age) throws IOException {
    System.out.println(name+"---"+age);
    // Processing data
    // Response data
    User user = new User();
    user.setAge(age);
    user.setUsername(name);
    user.setPassword("111");
    // Convert object to json type
    ObjectMapper om = new ObjectMapper();
    String json = om.writeValueAsString(user);
    System.out.println(json);
    // Response ajax
    response.setContentType("application/json;charset=utf-8");
    response.getWriter().write(json);
}
2.4.4 object object

The returned Student represents data.

Therefore, the general controller method returns the Object object, which is mostly used to process Ajax requests.

The returned Object can be List, Student, Map, String, Integer,... All are data (objects). All ajax requests need is data.

In ajax requests, the data that needs to be returned from the server is in json format. It is often necessary to process the conversion from java objects to json data. You also need to output data in response to ajax requests.

The framework provides the transformation from java objects to json data and the output of data.

1. Message converter HttpMessageConverter

This is an interface.

effect:

  1. Convert the requested data into java objects
  2. Convert the object returned by the controller method into data in different formats such as json, xml, text, binary, etc.

HttpMessgaeConverter interface source code:

MediaType: the requested data format, also known as media type. For example, JSON format data. The format of data in the Internet. (application/json,text/html,image/gif,. . . )

public interface HttpMessageConverter<T> {
  	/**
  	* Function: check whether the object of clazz type can be converted to the data format represented by mediaType
  			If it can be converted to the type represented by mediaType, return true, and call the read method with true
  	*/
    boolean canRead(Class<?> var1, @Nullable MediaType var2);
		/*
			It will receive the data in the request and convert the data into the object represented by clazz
		*/
  T read(Class<? extends T> var1, HttpInputMessage var2) throws IOException, HttpMessageNotReadableException;
 
 	/*
 		Judge whether to convert clazz this data type to the data format represented by mediaType
 		If true is returned, the write method is called
 	*/ 
  boolean canWrite(Class<?> var1, @Nullable MediaType var2);

    
		/*
			Turn the t object into json or xml according to the format described by var2 (content type)
			T The paradigm is the data type returned by the controller method
		*/
    void write(T var1, @Nullable MediaType var2, HttpOutputMessage var3) throws IOException, HttpMessageNotWritableException;
}

Common implementation classes of HttpMessageConverter interface:

  1. MappingJackson2HttpMessageConverter: use ObjectMapper of jackson tool library to convert objects to json data format
  2. StringHttpMessageConverter: convert and encode the data of string type.
2. Use implementation class

The framework automatically finds the implementation class used according to the return value of the controller method.

By default: springmvc uses four implementation classes of the HttpMessageConverter interface. Including Http MessageConverter.

Spring MVC needs to be labeled annotation driven: < MVC: annotation driver / > After adding this tag, after the spring MVC project is started, seven implementation class objects of the HttpMessageConverter interface will be created, including StringHttpMessageConverter and MappingJackson2HttpMessageConverter.

3. @ResponseBody

@The function of the ResponseBody annotation is to output the converted json of the User to the browser through the HttpServletResponse object.

4. Steps of converting the returned object of the controller method to json
  1. pom. jackson dependency is added to xml. By default, the spring MVC framework uses jackson to handle json
  2. Add the annotation driven tag to the configuration file of spring MVC
  3. Add @ ResponseBody annotation on the controller method to represent the return value data and output it to the browser.
/**
     * The object returned by the controller method is converted into json format data to respond to the client
     *
     * @return
     * @ResponseBody: This annotation will automatically output the json converted by the object to the browser and set the response header
     * Processing mode of framework:
     *      1.  The framework finds the implementation class of HttpMessageConverter interface according to the return value type of controller method. Then find the implementation class of json
     *      2.  Use the implementation class MappingJackson2HttpMessageConverter. Execute the write method. Convert the student object into json format data
     *      3.  The framework uses the ResponseBody annotation to output json data to the browser
     */
    @ResponseBody
    @RequestMapping("/ajaxUser.do")
    public User doAjaxUser(String name, Integer age) {
        User user = new User();
        user.setUsername(name);
        user.setPassword("123");
        user.setAge(age);
        return user;
    }
/**
     * If the controller method returns a collection, the corresponding json will be converted to array
     * @param name
     * @param age
     * @return
     */
    @ResponseBody
    @RequestMapping("/ajaxUserList.do")
    public List<User> doAjaxUserList(String name, Integer age) {
        User user = new User();
        user.setUsername(name);
        user.setPassword("123");
        user.setAge(age);
        User user1 = new User("222","222",222);
        List<User> list = new ArrayList<User>();
        list.add(user);
        list.add(user1);
        return list;
    }

 /**
     * The return value of the controller method is String, and the @ ResponseBody annotation is added to the method. The return value does not represent the view, but the data
     *
     * Whether the returned value of String is data or view depends on whether there is @ ResponseBody annotation on the method
     *
     * Default response header: content type: text / plain; Charset = Chinese garbled code in iso-8859-1
     * The filter we configured won't work because ajax requests go to the reply object by default
     *
     * Solve Chinese garbled Code: you need to use the products attribute of @ RequestMapping annotation to specify the value of content type
     * Frame processing String return value:
     *      1.  The framework uses StringMessageConverter
     *      2.  StringHttpMessageConverter Text / plain is used by default; Charset = iso-8859-1 character set
     * @param name
     * @param age
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/ajaxUserString.do" ,produces = "text/plain;charset=utf-8")
    public String doAjaxUserString(String name, Integer age) {
        User user = new User();
        user.setUsername(name);
        user.setPassword("123");
        user.setAge(age);
        return user.toString();
    }

2.5 interpreting mapping labels < URL pattern / >

2.5.1 configuration details
1. *.do

In the absence of special requirements, the < URL pattern / > of the DisptcherServlet, the central scheduler of spring MVC, often uses suffix matching, such as * do or * action, etc.

2. /

When we configure the mapping address to /, the central scheduler becomes the default servlet identity of tomcat, which can help us deal with static resources and requests that are not mapped to other requests** It is found that no matter pictures, js files, html static resource files, etc., can be requested successfully** Dynamic resources (jsp files are also handled by Tomcat) and requests configured for processing can be accessed normally.

The reason why static resource access fails is that we do not configure the corresponding controller object

<!--Configure central scheduler-->
    <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--Configure initialization parameters-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <!--Mapping method 2: use / -->
        <!--
            use / This makes the central scheduler the default default servlet
            Static resources and other unmapped requests need to be processed. The default central scheduler does not process the controller object of static resources, so the requests for static resources are 404
            If the mapping path configured in the project is / Dynamic resources can be accessed normally, while static resources cannot be accessed by policy. Access to static resources needs to be handled.
            -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
3. Processing of static resources

In fact: whether it's static pages (html), pictures, jsp files, js files, etc., it's actually Tomcat server that helps us deal with them. Only some Do and other requests are handled by our central scheduler. So in fact, the Tomcat container must also have a servlet to help us handle some static requests.

4. Default servlet of Tomcat

tomcat's default servlet is called default and helps us handle all requests that are not mapped to other requests.

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

		<servlet-mapping>
				<servlet-name>default</servlet-name>
      	<url-pattern>/</url-pattern>
		</servlet-mapping>

Default is the default servlet, which provides the processing of static resources and all requests that are not mapped to other requests. According to the configuration of tomcat's default servlet, the mapping path is /, and this default is to process other requests that we have not configured, so we can know that the priority of / must be relatively low.

Therefore, when we configure / dynamic resources for normal access, static resources cannot be accessed. Access to static resources needs to be handled.

2.5.2 the first method of processing static resources

Add the < MVC: default servlet handle > tag in the spring MVC configuration file. The spring MVC framework will add the DefaultServletHttpRequestHandle object when the project is running, so that this object can handle the access of static resources

This object will forward the received request address of static resources to tomcat to the default object for processing.

Advantages: simple solution

Disadvantages: it depends on the server tomcat to the default object. (this method is less used now)

Note: the annotation < MVC: default servlet handle > conflicts with @ RequestMapping. The solution is to declare the annotation driven tag in the configuration file.

<!--Configure annotation driven-->
    <mvc:annotation-driven/>
<!--Configure view parser-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/WEB-INF"/>
    </bean>
<!-- The first way of static resource processing-->
    <mvc:default-servlet-handler/>
2.5.3 the second way to solve static resources

Add a < MVC: Resources / > tag in the spring MVC configuration file, and the framework will create a resourceshttprequehandle controller object, which will be used to handle the access of static resources. Does not rely on Tomcat servers. Recommended.

This tag will also conflict with @ Requestmapping, so you also need to configure annotation driven tags.

    <!-- The second way of static resource processing-->
    <!--
    mapping: Access to static resources uri Address, wildcards can be used **
            ** :  Represents any directory and files under it
    location: Do not use the location of static resources in the project /WEB-INF catalogue
    -->
<!--The label can be used multiple times-->
    <mvc:resources mapping="/html/**" location="html/"/>

Advantages of Spring MVC

SSM framework integration

1. Integration ideas

SSM integration idea: Spring + spring MVC + mybatis

SSM integration uses the advantageous functions of the three frameworks, and the three layers of the three-tier architecture corresponding to the three frameworks. View layer business layer persistence layer

ssm integration is to hand over the objects to the container for management, and let the container create the java objects to be used in the project. Now there are two containers.

The first is the Spring container: the Spring container manages objects such as service s and dao. Is a container for business layer objects.

The second is the spring MVC container: the container that manages controller objects. Is a view layer object

SSM integration is to hand over objects to container management. Two containers coexist, each managing different objects. Declare the object in the configuration file and let the two containers create the object.

2. Creation and use of containers

Spring container creation: on the web XML declaration listener ContextLoader Listener. This functional framework has been written. The function is to create spring's container object webApplicationContext. When creating a webApplicationContext object, read the spring configuration file and the bean tags or annotations encountered, and then create service, dao and other objects and put them into the container for management.

WebApplicationContext spring = new WebApplicationContext('profile ')

Spring MVC container: on the web XML declares the DispatcherServlet of the central scheduler. In init methods such as this servlet, the container object WebapplicationContext is created. When creating this object, the configuration file of springmvc will be read. When reading the configuration file, when encountering the @ Controller annotation, the Controller object will be created and put into the container.

WebApplicationContext springmvc = new WebApplicationContext('profile ')

3. Relationship between two containers

In design, the Spring MVC container object is a sub container of the Spring container. It can be understood as inheritance in Java, but it is not real inheritance. Therefore, the child container can access the objects in the parent container.

4. Integration steps

  1. Create Maven web project

  2. Add dependent coordinates (spring, spring MVC, myabtis, mybatis spring, mysql driver, druid connection pool, jackson)

  3. Configure web XML files: declaring container objects

    1. Declare the Spring listener ContextLoaderListener: create the Spring container object, and create the service and dao layer objects
    2. Declare the central scheduler of spring MVC, create the spring MVC container, and create the controller layer object
    3. Declare the character set filter (provided by mvc) to solve the garbled code of post request
  4. Write the configuration files of Spring, Spring MVC and myabtis

  5. Java code, entity class, dao interface, mapper file, service, controller class, use annotation to declare objects and assign values

  6. Create view files and various JSPS

mybatis Config configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <typeAliases>
        <package name="com.mao.bean"/>
    </typeAliases>

    <mappers>
<!--        to configure package You need to ensure that the interface name and configuration file name are the same and under the same package-->
        <package name="com.mao.dao"/>
    </mappers>

</configuration>

Spring configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--Spring configuration file-->
    <!--    Annotation scanner-->
    <context:component-scan base-package="com.mao.service"/>

    <!--jdbc configuration file-->
    <context:property-placeholder location="classpath:conf/jdbc.properties"/>
    <!--    data source-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
    </bean>
    <!--    establish sqlSessionFactoryBean -->
    <bean id="factoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--Configure classes under the configuration file path mapper,No writing is required myabtis of config Configuration file-->
        <property name="configLocation" value="classpath:conf/mybatisConfig.xml"/>
    </bean>

    <!--establish dao Object, that is mapper Implementation class-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="factoryBean"/>
        <!--dao Layer interface-->
        <property name="basePackage" value="com.mao.dao"/>
    </bean>

    <!--    Spring Configuration of transactions-->

</beans>

Spring MVC configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--springmvc configuration file-->
    <!--    Declare component scanner control layer to mvc Manage-->
    <context:component-scan base-package="com.mao.web.controller"/>
    <!--Configure view parser-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--        prefix and suffix -->
        <property name="prefix" value="/WEB-INF/jsp"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--    Annotation driven
    1.  establish HttpMessageConverter Seven implementation class objects of the interface, processing Java Object to json Format conversion
    2.  Solve the problem of dynamic resource access failure in static resources
    -->
    <mvc:annotation-driven/>
</beans>

web.xml configuration

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<!--to configure Spring lsnrctl start -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:conf/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>


<!--    springmvc to configure-->
    <!--Configure central scheduler-->
    <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--Configure initialization parameters-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:conf/dispatcherServlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <!--Configure filter-->
    <filter>
        <filter-name>filter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

5. Path problem

In the project, sometimes there is /, sometimes there is no /, but sometimes the request can succeed. What's the problem?

Relative path problem

In the page, there is a path problem. The access path starts with / or does not start with /

<a href='test/some.do'>No slashes</a>
<a href='/test/some.do'>Slash</a>
<a href='http://www.baidu.com'></a>

Address difference:

  1. The beginning of the agreement is the absolute address. The address is unique and can be accessed directly.
  2. What does not start with a protocol is a relative path. When used alone, it does not represent a resource and cannot be accessed. The relative address must be together with the reference address for normal access.

Reference address: with slash /, without slash /, the two reference addresses are different.

Without slash: http://localhost/ssm/index.jsp

When we successfully enter a resource, the address will change http://localhost/ssm/test/some.do , then the reference address will change. Click again and you will find that the address is wrong. http://localhost/ssm/test/test/some.do

When there is no slash, the reference address and the current relative address will be combined to become the final access address.

Solution:

You can use the el expression ${pageContext.request.contextPath} to get the virtual directory of the current project. The advantage is that it is easy to understand, and the disadvantage is that it needs to be used everywhere.

You can also use the base tag of html. The function of this tag is to specify the default address or target for all links on the page, that is, the relative address of all addresses on the current page is the address specified by the base tag

<head>
  <base href='http://localhost/ssm/'/>
</head>
<%
 String basePath = request.getScheme() +":" + request.getServerName()+":" + request.getServerPort()+":"+
   request.getContextPath()+"/";
%>
<head>
  <base href='<%=basePath%>'/>
</head>

Begin with a slash (absolute path)

An address that begins with a slash will be directly in http://localhost Add the address with slash, that is, directly become http://localhost/test/some.do

Use the address starting with / and the reference address is the server address, that is, the location from the protocol to the port number. Virtual directory / ssm that will not contain the project

The solution is the first of the above solutions, which is solved by using el expression.

Spring MVC core technology

1. Request redirection and forwarding

Request forwarding:

Using forword for request forwarding, the implementation principle is request getRequestDispatcher(""). forward(req,resp)

@Controller
@RequestMapping("/test")
public class MyController2 {
    /**
     * The controller method returns ModelAndView to realize request forwarding
     * Syntax: MV Setviewname ("forward: full path of the view")
     * forward Features: if you don't work with the view parser, it will be regarded as if the view parser is not configured in the project
     * @return
     */
    @GetMapping("/forward.do")
    public ModelAndView doForward(){
        ModelAndView mv = new ModelAndView();
        // Forward is explicitly used for forwarding operations. Whether we add forward or not, we are forwarding operations,
        // However, only when we explicitly add the keyword forward: will we ignore the view parser,
        // Without this keyword, that is, when forward is omitted, we only need to write the name after adding the view parser
        // The meaning is that our files may not be in the directory configured by the view parser, so we can use this method to obtain the file views in other directories
        mv.setViewName("forward:/WEB-INF/show/forward.jsp");
        return mv;
    }
}

redirect

Using redirect to redirect, the implementation principle is response sendRedirect("");

/**
 * When the ModelAndView returned by the controller method implements redirection,
 * grammar
 * mv.setViewName("redirect:Full path "");
 * Feature: the view parser will also be ignored
 * Redirection function provided by the framework
 * 1.  The framework can realize the data transfer between two requests, convert the simple type data in the Model in the first request into a string, attach it to the back of the target page, and transfer the get parameters
 * You can get the parameter value in the target page
 *Get the value of the parameter. You can use ${param.xxx} to get the value of the parameter 
 * @return
 */
@GetMapping("/redirect.do")
public ModelAndView doRedirect() {
    ModelAndView mv = new ModelAndView();
    // Redirection cannot access the contents of WEB-INF
    mv.setViewName("redirect:/html/redirect.jsp");
    return mv;
}

2. Exception handling

2.1 how the spring MVC framework handles exceptions:

Use the @ ExceptionHandler annotation to handle exceptions. The framework handles exceptions in a centralized manner. Collect the exceptions thrown in the methods of each Controller class to one place for processing. Exception handlers are called exception handlers.

  1. @Exceptionhandler: placed above a method, indicating that this method can handle a certain type of exception. This method is executed when an exception occurs.
  2. @ControllerAdvice: put it on the class to indicate that there are exception handling methods in this class, which is equivalent to @ Aspect in aop. This annotation can be understood as Controller enhancement, which is the processing function of enhancing the function of the Controller class.

2.2 @ExceptionHandler

Use this annotation to specify a method as an exception handling method. This annotation has only one optional attribute value, which is a class <? > Array, which is used to specify the class to be processed by the annotated method, that is, the exception to be matched.

The return value of the annotated method can be ModelAndView, String, or void. The method name is optional. The method parameters can be Exception and its subclasses, HttpServletRequest, etc.

public class MyUserException extends Exception{
    public MyUserException() {
    }

    public MyUserException(String message) {
        super(message);
    }
}

public class NameException extends MyUserException{
    public NameException() {
    }

    public NameException(String message) {
        super(message);
    }
}

public class AgeException extends MyUserException{
    public AgeException() {
    }

    public AgeException(String message) {
        super(message);
    }
}

package com.mao.web.handle;

import com.mao.web.exception.AgeException;
import com.mao.web.exception.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Description @ControllerAdvice Indicates that the current class is an exception handling class
 * @Author Hairy
 * @CreateDate 2021/06/13/Sunday 1:35 PM
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    // The method of handling exceptions is defined in the same way as in the Controller class

    /**
     * Exception Represents the exception object thrown by the method in the Controller class. We will receive any exception thrown by the processed method
     *
     * @param e
     * @return
     * @ExceptionHandler: Indicates that this method handles exceptions
     * Attribute value: the value is an exception type
     */
    @ExceptionHandler(value = NameException.class) // Indicates that this method handles exceptions
    public ModelAndView doNameException(Exception e) {
        System.out.println(e);
        // After an exception occurs, we can record the exception log, send a notice to the programmer, and give user-friendly tips, etc
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "Wrong name!");
        mv.setViewName("redirect:/fail.jsp");
        return mv;
    }

    @ExceptionHandler(value = AgeException.class) // Indicates that this method handles exceptions
    public ModelAndView doAgeException(Exception e) {
        System.out.println(e);
        // After an exception occurs, we can record the exception log, send a notice to the programmer, and give user-friendly tips, etc
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "Wrong age!");
        mv.setViewName("redirect:/fail.jsp");
        return mv;
    }

    @ExceptionHandler() // Indicates that this method handles unknown exceptions, that is, any type of exception has the lowest priority,
    // Only when the error type is not caught by the exception handling method, the error method will be executed by the method
    public ModelAndView doOtherException(Exception e) {
        System.out.println(e);
        // After an exception occurs, we can record the exception log, send a notice to the programmer, and give user-friendly tips, etc
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "Wrong!");
        mv.setViewName("redirect:/fail.jsp");
        return mv;
    }
}

**It should also be noted that when our framework redirects, the data of the request field will be spliced behind the redirected address in the form of query string, that is, for the initiated get request, we can obtain the parameter value in the form of ${param.xxx} * * of el expression on the new page.

3. Interceptor

Interceptor, the interceptor in Spring MVC, is very important and useful. Its main function is to intercept specified user requests and carry out corresponding preprocessing and post-processing.

Interceptor: it is an object in the framework and needs to implement the interface HandlerInterceptor. Intercept user requests. To be precise, it is to intercept the request before the Controoler method processes it.

Function: you can process the request in advance, and then decide whether to execute the Controller according to the processing results. You can also define functions shared by multiple controllers to interceptors.

characteristic:

  1. Interceptors are divided into system interceptors and user-defined interceptors.
  2. There can be multiple interceptors in a project.
  3. Interceptors focus on intercepting user requests.
  4. The interceptor is executed before the Controller executes the corresponding request.

3.1 definition of interceptor

  1. To create an interceptor, you need to let this class implement the interface HandlerInterceptor and three methods in the interface.
  2. Declare the interceptor object in the configuration file (the configuration file of mvc) and specify the uri address of interception

Definition of interceptor class;

package com.mao.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description
 * @Author Hairy
 * @CreateDate 2021/06/13/Sunday 3:03 PM
 */
public class MyInterceptor implements HandlerInterceptor {
    /**
     * preHandle: Method parameters for preprocessing requests: Three
     *
     * @param request
     * @param response
     * @param handler  This parameter refers to the intercepted controller object (controller) method
     * @return The Boolean value of true indicates that the request is correct, which means that it is released and let the controller method handle it. All three interceptor methods will be executed.
     * <br>           false The request is intercepted and cannot be executed by the controller method. Only the interceptor method will be executed, and the other two will not be executed. The request ends here.
     * Features: this method is executed before the execution of the controller method. It can preprocess the request, perform login inspection, authority judgment, statistical data, etc
     * You can decide whether to execute the request
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle .... 111111111111");
        return true;
    }

    /**
     * postHandle: Post processing method
     *
     * @param request
     * @param response
     * @param handler      Intercepted controller object
     * @param modelAndView The return value of the controller method, that is, the return value of the request
     *                     Features: executed after controller method
     *                     The execution result of the controller method can be obtained. The original execution result can be modified. You can modify data and views.
     *                     Function: it can be used for secondary processing of requests
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle 22222222");
        // Secondary processing of data
        modelAndView.addObject("username", request.getParameter("name") + "mao");
    }

    /**
     * afterCompletion Method of final execution
     *
     * @param request
     * @param response
     * @param handler  Intercepted controller object
     * @param ex       Exception object
     *                 Features: this method is executed after the request is completed. The sign of request completion processing is that the view processing is completed, and the forwarding operation is performed on the view
     *                 That is, the user has received the response result.
     *                 This method is generally the last work of the program. It can free memory and clean up temporary variables, such as deleting some values in the session field
     *                 Execution conditions of the method:
     *                 The preHandle() method of the current interceptor must be executed
     *                 And the return value of the preHandle method must be true
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion ... 33333333");
    }
}

Declaration of interceptor in configuration file;

<!--Declaration interceptor-->
    <mvc:interceptors>
        <!--First interceptor-->
        <mvc:interceptor>
            <!--The interceptor is going to intercept uri address,Wildcards can be used ** -->
            <!-- Intercept to /ssm/ Start request-->
            <mvc:mapping path="/ssm/**"/>
            <!--Non intercepted address-->
            <mvc:exclude-mapping path="/test/**"/>
            <!--Specifies the number of characters used by this interceptor bean class-->
            <bean class="com.mao.web.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

3.2 multiple interceptors

Use two interceptors to see the execution order of the interceptor and which method controls the execution of the request.

package com.mao.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description
 * @Author Hairy
 * @CreateDate 2021/06/13/Sunday 3:03 PM
 */
public class MyInterceptor2 implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("2222222222 preHandle .... ");
        return true;
    }


    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("22222222222222 postHandle ");
        // Secondary processing of data
        modelAndView.addObject("username", request.getParameter("name") + "mao22");
    }


    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("2222222222222222 afterCompletion ... ");
    }
}

  1. When the return value of the preHandle of both interceptors is true

    11111111111111 preHandle .... 
    2222222222 preHandle .... 
    doSome ..........
    22222222222222 postHandle 
    11111111111111111postHandle . . . . . 
    2222222222222222 afterCompletion ... 
    11111111111111 afterCompletion ...
    
  2. When the first preHandle is true and the second is false

    11111111111111 preHandle .... 
    2222222222 preHandle .... 
    11111111111111 afterCompletion ... 
    

    It is found that the afterCompletion method of the first interceptor is executed. This is because the return value of the first interceptor is true, so the execution conditions are met.

  3. The first preHandle is false, and the second is true or false

    11111111111111 preHandle .... 
    

3.3 why use multiple interceptors

  1. Distribute the verification function to independent interceptors. Each interceptor performs a single verification process
  2. Combine multiple interceptors.

3.4 summary

Multiple interceptors are threaded on a chain, and multiple interceptors and a controller object are on a chain. Handler execution chain (processor execution chain) is used in the framework to represent this execution chain.

public class HandlerExecutionChain {
    private final Object handler; // Controller object
  	private Handlerinterceptor[] interceptors;// To store multiple interceptor objects. MyInterceptor 
    private final List<HandlerInterceptor> interceptorList;
}

The interceptor implements the execution sequence of 12 and 21 by traversing the array Handlerinterceptor[] interceptors

3.5 comparison between interceptor and filter

  1. Interceptors are objects in the mvc framework. Filters are objects in servlet s
  2. The interceptor object is created by the framework container, and the filter object is created by the Tomcat container. (the filter is handwritten by us, but the object is created by tomcat, and it is only created when the server is started and automatically destroyed when the server is destroyed)
  3. The interceptor focuses on the judgment of the request, and can truncate the request. The filter focuses on setting values for the attributes and parameters of request and response objects. For example, request setCharacterEncoding().
  4. There are three execution opportunities for the interceptor, before the controller method, after the request is completed. The filter is executed before the request. (of course, the filter can also be processed after release)
  5. Interceptor is used to intercept requests for controller and dynamic resources. Filters can filter all requests, both dynamic and static.
  6. If the interceptor and filter exist at the same time, the filter is executed first (why the filter is executed first, because it is defined in the servlet specification), followed by the central scheduler (assign the request to the method in the specified controller class), and finally the interceptor, and then the controller method.

4. Internal execution process of spring MVC

flow chart:

Internal process: (ignore tomcat)

  1. The user initiates the request and gives it to the central scheduler (dispatcher servlet)

  2. The central scheduler passes the request to the processor mapping.

    Processor mapper: an object in the spirngmvc framework, which needs to implement the interface HandleMapping. The interface is implemented by mappers.

    Function: get the controller object from the spring MVC container, put the found controller and interceptor objects into the processor execution chain object, save and return to the central scheduler. (ApplicationContext.getBean() )

  3. The central scheduler gives the controller object in the processor execution chain to the processor adapter.

    Processor adapter: an object in the spring MVC framework that implements the HandleAdapter interface

    Function of adapter: execute the method of controller, that is, execute mycontroller Dosome() method. Get the result ModelAndView and submit the result to the central scheduler.

  4. The central scheduler sends the execution result of the controller to the view parser again,

    View parser: an object in the spring MVC framework, which needs to implement the ViewResolver interface.

    Function of View parser: handle the of the View, form the complete path of the View, and create View type objects

  5. The central scheduler calls the View class method and puts the data in the Model into the request scope. Perform a forward operation on the View.

Keywords: Java Mybatis Spring Back-end Spring MVC

Added by Forever_xxl on Sat, 29 Jan 2022 09:01:56 +0200