Spring MVC detailed summary and analysis

Spring MVC learning

Brief introduction to spring MVC framework:

Spring MVC is a module of spring framework. Spring MVC and spring do not need to be integrated through the middle integration layer.
Spring mvc is a web framework based on mvc.
Spring MVC presentation layer: it is convenient for front and back data transmission
Spring MVC has a controller, which is similar to Struts. It receives external requests, parses parameters and passes them to the service layer
MVC refers to the design concepts of C control layer, M module layer and V view layer, and SPRING MVC itself is the MVC framework in SSM framework, The function is to help (in a sense, it can also be understood as constraints) we should develop WEB projects according to the design of MVC, and the other two frameworks spring are mainly used as IOC,AOP and other design principles. As for mybatis, it is used to facilitate the operation of databases, so they are all in MV. As for V, it refers to the display part, generally refers to JSP and freemarks. In fact, it is similar to SSM It doesn't matter much

Spring MVC project running process

Spring MVC project operation flow chart

Analysis of spring MVC Architecture Principle

1. Initiate a request to the front-end controller (dispatcher servlet)
2. The front-end controller requests HandlerMapping to find the Handler, which can be found according to xml configuration and annotation
3. Processor mapper HandlerMapping returns a Handler to the front end controller
4. The front-end controller calls the processor adapter to execute the Handler
5. The processor adapter executes the Handler
6. The Handler returns ModelAndView to the adapter after execution
7. The processor adapter returns ModelAndView to the front controller. ModelAndView is an underlying object of the spring MVC framework, including Model and view
8. The front-end controller requests the view parser to parse the view and parse it into a real view (jsp) according to the logical view name
9. The View parser returns View to the front controller
10. The front-end controller performs view rendering, which fills the request field with model data (in the ModelAndView object)
11. The front-end controller responds to the user

The above is the running process of spring MVC, which is mainly to submit requests to the tomcat server, and the spring MVC project is configured to send requests through the dispatcher servlet, The dispatcher servlet takes the requested address and location to find the Controller in the project (the class annotated with @ Controller is the Controller), finds all controllers, and then traverses the Controller to find all methods that can process the request (example: @ RequestMapping annotated class is a method that can process requests, which is just one. Several other annotations will be described below, which also indicate that this is a method to process requests.) then find the corresponding processing method (@ RequestMapping annotated value result value). The method execution result will be returned to the page (later).

A simple Spring MVC project

The three main files of spring MVC project, web XML (configure the operation of the project after accessing tomcat), SpringMVC.xml(SpringMVC framework configuration file), Controller (Controller, actual operation class after request). Of course, it is also very important to use pox file if maven project is used

: pox file

First import two necessary jar package dependencies

		<!-- servlet Dependence, web Project must depend on-->
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

		<!-- SpringMVC Dependency. This dependency package already contains Spring Required dependencies for-->
        	<dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>

: web.xml file

<?xml version="1.0" encoding="UTF-8"?>
<web-app
         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">
    <servlet>
<!--        The request is loaded into the front-end controller for a series of operations-->
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--        Load frame related configurations into the frame container from springmvc-servlet.xml Configuration in file-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

<!--    Any request must go through springmvc This controller-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

: springmvc-servlet.xml 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
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
         http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        ">
<!-- Start annotation scanning and load the corresponding annotation into the Spring Container, now mainly scan controller annotations -->
    <context:component-scan base-package="com.ling.UserController"/>
    
       <!--Declarative view parser: help with views-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- Request prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- Request suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

: controller operation class

After accessing the data, all operations are performed in this layer

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

//Annotation marked as controller
@Controller
public class StudentController {

    //Access mapping annotation (the access path is the project default path + / ling)
    @RequestMapping("/ling")
    public String ling(){
        System.out.println("visit ling Method already operated!");

        //Here, the returned value represents the forwarding address. The value is spliced with the pre suffix of the view parser. The address result is: / WEB-INF / JSP / Chen JSP. If the file is not found, the forwarding fails
        return "chen";
    }
}

Because of my Chen The JSP file is under WEB-INF/jsp, so the prefix of the view parser must be written as / WEB-INF/jsp /. The reason for trying to put the file into WEB-INF/jsp is to prevent direct access to the page.


If there is an error, please first observe whether the compiled folder is correct (always believe that your code is right, the wrong is the world). My beginner also stuck here for a period of time, and I couldn't access it anyway. As a result, there was a problem with the compiled file.

Controller content learning

@Controller annotation

The Controller annotation is used at the top of the class to indicate that it is a Controller. After being scanned by Spring, it will be loaded into the Spring container. After accessing, the previously configured DispatcherServlet will find all classes with @ Controller annotation, find the methods with @ RequestMapping annotation, and find the corresponding mapping for operation.

@RequestMapping annotation

@The RequestMapping annotation can be used in two places, one above the class and the other above the method.

It is used above the method to represent the mapping of the access path. The access path corresponds to the value value of @ RequestMapping. If there is only one attribute in @ RequestMapping, value can be omitted and the value can be written directly.

@Controller
@RequestMapping("/Student")
public class StudentController {

    @RequestMapping(value = "/ling")
    public String ling(){
        System.out.println("visit ling Method already operated!");

        return "chen";
    }
}

It is used above the class to represent the mapping name of a module. To access all methods under this class, you must add the module path to its original mapping path. For example, if you want to access the ling() method, you must access: / Student/ling.

@RequestMapping setting access method:

@RequestMapping can set its access method and method property

method:

RequestMethod.POST: post access method

RequestMethod.GET: get access method

Example:

    @RequestMapping(value = "/ling",method = RequestMethod.POST)
    public String ling(){
        System.out.println("visit ling Method already operated!");

        return "chen";
    }
}

Access method:

<form action="/Student/ling" method="post">
  <input type="text" placeholder="Please enter the account number"/><br>
  <input type="submit" value="Submit"/>
</form>

Draw inferences from one example. You can set an access method in the method, and you should also set the access method of the whole module

@Controller
@RequestMapping(value = "/Student",method = RequestMethod.GET)
public class StudentController {

    @RequestMapping(value = "/ling")
    public String ling(){
        System.out.println("visit ling Method already operated!");

        return "chen";
    }
}

Submit by post

The post request reports an error, and then test the get request method.

So it's really feasible. Let's play another idea. Set different request access methods on classes and methods at the same time to see which is the standard for the results.

@Controller
@RequestMapping(value = "/Student",method = RequestMethod.GET)
public class StudentController {

    @RequestMapping(value = "/ling",method = RequestMethod.POST)
    public String ling(){
        System.out.println("visit ling Method already operated!");

        return "chen";
    }
}

First use get request

get is feasible. Test the post request again

The conclusion is that it is no different from no setting. Both post requests and get requests are OK.

parameter

servlet's own parameters

Spring MVC provides three parameters HttpServletRequest, httpservletresponse and httpsession that are assigned by the method. As long as these parameters are included in the method, spring MVC will assign values automatically, so that the request header and session information sent by the page can be obtained. When jumping to the page, it will automatically jump to the new page with the information after operation. As long as the servlet is requested, it will come with this information. If you want to use it, you can use it in the parameters of the request mapping method. Look at the following examples.

@RequestMapping(value = "/demo1")
    public String demo1(HttpServletRequest request){

        System.out.println("demo1 operation:");

        HttpSession session = request.getSession();

        if (session != null){
            System.out.println("session Presence.");
            Object password = session.getAttribute("password");
            if(password != null){
                System.out.println("password existence");
            }else {
                System.out.println("password non-existent");
                session.setAttribute("password",true);
            }
        }
        return "chen";
    }

    @RequestMapping(value = "demo2")
    public String demo2(HttpServletRequest request){

        System.out.println("demo2 operation:");

        HttpSession session = request.getSession();

        if (session != null){
            System.out.println("session Presence.");
            Object password = session.getAttribute("password");
            System.out.println(password != null? "password existence":"password non-existent");
        }
        return "chen";
    }

    @RequestMapping(value = "demo3")
    public String demo3(HttpSession session){

        System.out.println("demo3 operation:");

        if (session != null){
            System.out.println("session existence");
            Object password = session.getAttribute("password");
            if (password != null){
                session.removeAttribute("password");
            }else {
                System.out.println("password non-existent");
            }
        }
        return "chen";
    }

Access demo1 - > demo2 - > demo3 - > demo2 in turn

Execute terminal results

Receive front-end data with custom parameters

Receive one by one

Receive the parameters from the front end one by one. The parameter name in the method must match the name of the data from the front end to receive the data

@RequestMapping("/parametric")
    public String parametric(String name,String paw){

        System.out.println("name="+name);

        System.out.println("paw="+paw);

        return "chen";
    }
 <form action="/Student/parametric" method="get">
    <input type="text" placeholder="Please enter the account number" name="name"/><br>
    <input type="text" placeholder="Please input a password" name="paw"/><br>
    <input type="submit" value="Submit"/>
  </form>

Change the name of the data transmitted from the front end to see the results

<form action="/Student/parametric" method="get">
    <input type="text" placeholder="Please enter the account number" name="name"/><br>
    <input type="text" placeholder="Please input a password" name="password"/><br>
    <input type="submit" value="Submit"/>
  </form>

As a result, the data is not received. Without modifying the front-end parameter name and method parameters, the parameter name passed can be marked with the @ RequestParam annotation. Example:

/**
 * Receive the request parameters one by one. The parameter name and formal parameter name in the request are different
 * @RequestParam : Solve the problem of different names
 *       Attribute: parameter name in value request
 *              required : boolean Type. The default is true
 *                    true: This parameter must be present in the request and no error is reported.
 *                    false: This parameter can not be in the request.
 *       Position: in front of parameter definition
 */

@RequestMapping("/parametric")
    public String parametric(String name,@RequestParam(value = "password",required = false) String paw){

        System.out.println("name="+name);

        System.out.println("paw="+paw);

        return "chen";
    }
Object receiving

The method of object receiving requires that the data parameters passed from the front end must match the properties of the object to receive data. If the front end data parameters do not have the name in the object properties, the property is null.

Example:

public class Student {
 // The property name is the same as the parameter name in the request
 //age is a redundant attribute. The front end does not have this parameter
    private String name;
    private String paw;
    private String age;
    // set| get method
}

@RequestMapping(value = "demo4")
    public String demo4(Student user){

        System.out.println("demo4 operation:");

        System.out.println(user.toString());

        return "chen";
    }

result:

Controller method return type

The return value of the controller method represents the processing result of this request. The return values include modelandview, string, void and object (of any type). In general, the return result of the request is two: data + attempt. You can only operate on the server content without returning. The following describes each return type.

1.ModelAndView data and view

The results of the request have data and views, and ModelAndView is the most convenient

Data: store the request scope.

View: performing forward forwarding operations

Example:

Create the view file first

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>View</title>
</head>
<body>
    <%--Used to receive data from the server--%>
		Data: ${mydata}
</body>
</html
@RequestMapping("/test1")
    public ModelAndView test1(){

        System.out.println("test1 operation:");

        ModelAndView mav = new ModelAndView();
        //Store data. The bottom layer is addAttribute in request
        mav.addObject("mydata","This data will be returned to the front page");
        //Forwarding view address
        mav.setViewName("/View");
        return mav;
    }

Forward to the View view and display the brought data.

2.String view

The return value of the framework pair is String, and the forward forwarding operation is performed.

Views can be represented as full view paths or logical names of views

@RequestMapping(value ="/return-string-view.do")
public String doReturnStringView1() {
        System.out.println("Yes MyController of doReturnStringView1 method name=");
      
        //Return the result, forward, and forward to show jsp
        //Logical name, view parser needs to be configured
        return "show";
}


@RequestMapping(value ="/return-string-view2.do")
public String doReturnStringView2() {
    System.out.println("Yes MyController of doReturnStringView2 method name=");
    //Full view path, cannot use view parser
    return "/WEB-INF/jsp/show.jsp";

}

3. void has no data and view

void: without data and view, you can use the HttpServletResponse object to output data and respond to ajax requests.

Because HttpServletResponse can be used in the method, and the HttpServletResponse will be automatically returned to the page after the method ends, you can operate HttpServletResponse to achieve the desired effect.

4 .Object

Returns whether Student represents data or view. So the controller method returns the Object object, which is used to respond to ajax requests.

The returned Object can be List, Student, Map, String, Integer... These are all data, and the ajax request needs data. In ajax requests, the data that needs to be returned from the server is in json format, and the conversion from Java objects to json is often handled. You also need to output data in response to ajax requests. The framework provides the work of processing java Object to json conversion or data output.

HttpMessageConverter message converter

The HttpMessageConverter interface is used to 1) convert the requested data into java objects, and 2) convert the objects returned by the controller method into data in different formats such as json, xml, text, binary, etc.

The prerequisite for HttpMessageConverter to convert objects into json data is the jar package required to convert data

Import jar package

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

According to the return type of the controller method, the framework automatically finds the implementation class used and converts it into json data

By default (sufficient for json conversion): springmvc uses four implementation classes of the httpmessageconverter interface, including StringHttpMessageConverter

In the spring MVC configuration file, add the annotation driven label MVC: annotation driven 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.

@ResponseBody

@The function of the ResponseBody annotation is to output the json after Object conversion to the browser through the HttpServletResponse Object.

As long as the @ ResponseBody annotation is added, it will be returned to the page as data, so String with this annotation will no longer forward the page, but return the content data in the String.

The controller method returns the step of converting the object to json
  1. pom. jackson dependency is added to XML, and the spring MVC framework uses jackson by default to handle json

  2. In the spring MVC configuration file, add the annotation driven label MVC: annotation dirty (in fact, it can not be added. By default, it seems that this function can be implemented. Add several more classes when the project is started)

  1. Add the @ ResponseBody annotation on the controller method to represent the return value data and output it to the browser.

Static resource processing

There is a default setting in the Tomcat server, which is mainly used to find project resources. If the central scheduler sets "/", the project setting conflicts with the default setting of tomcat, so if the central scheduler sets "/, Then all requests will go through the dispatcher servlet (dynamic resource access), and the static resources will not be found. There are two ways to solve this situation.

The first approach deals with static resources

Add the MVC: default servlet handler tag to the spring MVC configuration file. The spring MVC framework will add the DefaultServletHttpRequestHandler object to handle the access of static resources when the project is running.

<!--Declarative annotation driven
    default-servlet-handler and@RequestMapping Conflicting use
-->
<mvc:annotation-driven />

<!--The first way to declare static resources
    establish DefaultServletHttpRequestHandler Processing static resources.
    DefaultServletHttpRequestHandler Forward the address of the received static resource to tomcat of default

    advantage:
      The solution is simple
    Disadvantages:
      rely on tomcat The capabilities provided by the server.
-->
<mvc:default-servlet-handler />

The second is the processing method of static resources

Add an mvc:resources tag to the spring MVC configuration file, and the framework will create a ResourceHttpRequestHandler controller object, which will be used to handle the access of static resources. It does not depend on the tomcat server. Recommended.

 <!--Declarative annotation driven
        resources and@RequestMapping There is a conflict in use. To set this label and cancel the conflict. Otherwise, dynamic resource requests cannot be made
    -->
    <mvc:annotation-driven />

    <!--The second way to declare static resources
        mapping: Access to static resources uri Address, wildcards can be used(**). 
                  ** : Represents any directory and resource name
        location: Do not use the location of static resources in the project/WEB-INF catalogue

    -->
    <mvc:resources mapping="/images/**" location="/images/" />
    <mvc:resources mapping="/html/**" location="/html/" />
    <mvc:resources mapping="/js/**" location="/js/" />



    <!--In one sentence, set up static resources: put all folders into one folder-->
    <!--<mvc:resources mapping="/static/**" location="/static/" />-->

Keywords: Java Maven Spring Tomcat mvc

Added by mallard on Fri, 17 Dec 2021 11:55:55 +0200