Spring MVC tutorial and principles

Posted by DRTechie on Mon, 03 Jan 2022 11:22:03 +0100

SpringMVC

ssm: mybatis + Spring + spring MVC MVC three-tier architecture

1. What is MVC:

MVC is the abbreviation of Model, View and Controller. It is a software design specification

Previous Servlet processing:

  1. User sends request
  2. The Servlet accepts the requested data and calls the corresponding business logic method
  3. After the business is processed, the updated data is returned to the servlet
  4. servlet turns to JSP, which renders the page
  5. Respond to the front-end updated page

mvc:

Controller layer:

  1. Get form data
  2. Call business logic
  3. Go to the specified page

Model layer:

  1. Business logic
  2. Status of saved data

View:

  1. Display page

1 review Servlet

  1. Create Maven project directly without adding other projects

  2. Import parent dependency

    <!--Parent project import dependency-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.12</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
    

3. Add as web project

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-v1HuQF1U-1640585948380)(E:\Typroa notes \ SpringMVC.assets\image-20211204113028384.png)]

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-7moAKHD5-1640585948384)(E:\Typroa notes \ SpringMVC.assets\image-20211204113106118.png)]

Steps:

  • Create a java class to inherit HttpServlet

  • Override doGet and doPost methods

    package com.smile.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1. Get front-end parameters
            String method = req.getParameter("method");
            if (method.equals("add")){
                req.getSession().setAttribute("msg","Yes add method");
            }
            if (method.equals("delete")){
                req.getSession().setAttribute("msg","Yes delete method");
            }
            //2. Call the business layer
    
            //3. View forwarding or redirection
            req.getRequestDispatcher("/WEB-INF/jsp/text.jsp").forward(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           doGet(req, resp);
        }
    }
    
  • On the web Configuration in XML

    <?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">
    
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.smile.servlet.HelloServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
        <!--<session-config>
            <session-timeout>15</session-timeout>
        </session-config>-->
        <!--Default welcome page-->
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>
    

2 central controller (dispatcher servlet)

Spring's web framework is designed around the dispatcher servlet, which is used to distribute requests to different processors. From spring 2 Starting with Java 5 or above, users can adopt annotation based @ Controller declaration.

2.1 the principle of spring MVC is shown in the following figure:

When a request is initiated, the front controller intercepts the request, generates a proxy request according to the request parameters, finds the actual controller corresponding to the request, processes the request, creates a data model, accesses the database, and responds to the model to the central controller. The controller renders the view result using the model and view, and returns the result to the central controller, The result is then returned to the requester.

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-don8DkSz-1640585948385)(E:\Typroa notes \ SpringMVC.assets\image-20211204124345134.png)]

2.2 spring MVC implementation principle

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-4OTPCYVH-1640585948387)(E:\Typroa notes \ SpringMVC.assets\image-20211204133851351.png)]

The figure shows a relatively complete flow chart of spring MVC. The solid line indicates the technology provided by the spring MVC framework, which does not need to be implemented by developers, and the dotted line indicates that it needs to be implemented by developers.

Briefly analyze the implementation process

Dispatcher servlet represents the front controller and is the control center of the whole spring MVC. When the user sends a request, the dispatcher servlet receives the request and intercepts the request.

We assume that the requested url is: http://localhost:8080/SpringMVC/hello

As above, the url is divided into three parts:

http://localhost:8080 Server domain name

Spring MVC is a web site deployed on the server

hello indicates the controller

Through analysis, the above url is expressed as: request the hello controller of the spring MVC site located on the server localhost:8080.

HandlerMapping is processor mapping. DispatcherServlet calls HandlerMapping, which looks up the Handler according to the request url.

HandlerExecution refers to a specific Handler. Its main function is to find the controller according to the url. The controller found by the url above is: hello.

HandlerExecution passes the parsed information to DispatcherServlet, such as parsing controller mapping.

The HandlerAdapter represents a processor adapter that executes the Handler according to specific rules.

The Handler lets the specific Controller execute.

The Controller returns the specific execution information to the HandlerAdapter, such as ModelAndView.

The HandlerAdapter passes the view logical name or model to the dispatcher servlet.

DispatcherServlet calls the view resolver to resolve the logical view name passed by the HandlerAdapter.

The view parser passes the parsed logical view name to the dispatcher servlet.

DispatcherServlet calls a specific view according to the view result parsed by the view parser.

2.2. 1. XML code: understand the above principles:

web.xml

<?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">

 <!--1.register DispatcherServlet-->
 <servlet>
     <servlet-name>springmvc</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <!--Associate a springmvc Configuration file for:[servlet-name]-servlet.xml-->
     <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:springmvc-servlet.xml</param-value>
     </init-param>
     <!--Startup level-1-->
     <load-on-startup>1</load-on-startup>
 </servlet>

 <!--/ Match all requests; (excluding.jsp)-->
 <!--/* Match all requests; (including.jsp)-->
 <servlet-mapping>
     <servlet-name>springmvc</servlet-name>
     <url-pattern>/</url-pattern>
 </servlet-mapping>
</web-app>

springmvc-servlet

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

 <!--Add process mapper-->
 <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
 <!--Add processor adapter-->
 <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
 <!--Adding: View parser:DispatcherServlet Give it to him ModelAndView   Later can be changed to Themyleaf Freemarker-->
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
     <!--prefix-->
     <property name="prefix" value="/WEB-INF/jsp/"/>
     <!--suffix-->
     <property name="suffix" value=".jsp"/>
 </bean>

 <!--Handler-->
 <bean id="/hello" class="com.smile.controller.HelloController"/>
</beans>

HelloController

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller {
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
     //ModelAndView models and views
     ModelAndView mv = new ModelAndView();

     //Encapsulate the object and place it in ModelAndView. Model
     mv.addObject("msg","HelloSpringMVC!");
     //Encapsulate the view to jump to and put it in ModelAndView
     mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
     return mv;
 }
}
2.2. 2 annotated spring MVC [key]

Note: in the view parser, we put all the views in the / WEB-INF / directory, which can ensure the view security, because the files in this directory cannot be accessed directly by the client

Steps:

  1. Create a new web project

    <?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">
    
        <!--1.register DispatcherServlet-->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--Associate a springmvc Configuration file for:[servlet-name]-servlet.xml-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-servlet.xml</param-value>
            </init-param>
            <!--Startup level-1-->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--/ Match all requests; (excluding.jsp)-->
        <!--/* Match all requests; (including.jsp)-->
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  2. Import related jar packages

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>springMVC</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        //Note here
        <modules>
            <module>spring-01-servlet</module>
            <module>spring-02-hellomvc</module>
            <module>spring-02-hellomvc2</module>
            <module>spring-03-annocation</module>
        </modules>
    
        <!--Parent project import dependency-->
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.3.12</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
        </dependencies>
    
        <!--maven Resource filtering problem-->
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
        </build>
    
    </project>
    
  3. Write web XML, register DispatcherServlet

    <!--1.register DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--Associate a springmvc Configuration file for:[servlet-name]-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--Startup level-1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!--/ Match all requests; (excluding.jsp)-->
    <!--/* Match all requests; (including.jsp)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!--Configure custom garbled filter-->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.smile.filter.GenericEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  4. Writing spring MVC configuration files

    <?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">
    
        <!--Automatically scan the package to make the comments under the specified package effective, and IOC Unified container management-->
        <context:component-scan base-package="com.smile.controller"/>
        <!--Give Way SpringMVC Do not process static resources, for example:.css  .js .html Wait, or something will go wrong-->
        <mvc:default-servlet-handler />
        <mvc:annotation-driven/>
        <!--Adding: View parser:DispatcherServlet Give it to him ModelAndView   Later can be changed to Themyleaf Freemarker-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
            <!--prefix-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--suffix-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
    </beans>
    
  5. Create the corresponding control class: controller

    package com.smile.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    
    @Controller
    @RequestMapping("/hello")
    public class HelloController {
        //Real access address: project name / HelloController/hello
        @RequestMapping("/h1")
        public String hello(Model model){
            //Encapsulating data: adding attributes msg and values to the model can also be used on the page
            model.addAttribute("msg", "helloSpringMVC Annocation ok");
            //web-inf/jsp/hello.jsp
            return "hello";   //Will be processed by the view parser
        }
    }
    
  6. Improve the correspondence between the front-end view and the controller

  7. Test run commissioning

Three major components that must be configured to use spring MVC:

Processor mapper, processor adapter, view parser

In the annotation, we only need to manually configure the view parser, while the processor mapper and processor adapter only need to turn on the annotation instead.

3 RequetMapping

@RequestMapping: annotations are used to map URLs to a controller class or a specific handler method. It can be used on a class or method. For a class, it means that all methods in the class that respond to requests take this address as the parent path.

4RestFul style

Restful is a style of resource location and resource operation. It's not a standard or agreement, it's just a style. The software designed based on this style is more concise, more hierarchical, and easier to implement caching and other mechanisms.

package com.smile.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class RestFulController {
    //customary: http://localhost:8080/add?a=1&b=3
    //RestFul: http://localhost:8080/add/a/b
    //When RestFul is used, @ PathVariable modifies the request path for the request parameters at the same time. Different request methods Post or Get access the corresponding path,

//    @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
    @GetMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int res = a+b;
        model.addAttribute("msg","result is :"+res);
        return "test1";
    }
    @PostMapping("/add/{a}/{b}")
    public String test2(@PathVariable int a, @PathVariable int b, Model model){
        int res = a+b;
        model.addAttribute("msg","result2 is :"+res);
        return "test1";
    }
}
Combined notes:

@GetMapping

@PostMapping

@DeleteMapping

@PutMapping

@PatchMapping

5 spring MVC data processing

5.1 redirection and forwarding
//When a view parser is not required:
@PostMapping("/m1/t1")
public String test3(Model model){
    model.addAttribute("msg","result2 is :"+res);
    //Redirection: the address will change
    return "redirect:/test1.jsp";
    //Forwarding: the address will not change
    return "test1";

}
5.2 back end data processing

1. The submitted domain name is consistent with the parameter name of the processing method

Submit data: http://localhost:8080/hello?name= Jia Furong

Treatment method:

@RequestMapping("/hello")
public String hello(String name){
    System.out.println(name);   //Jia Furong
    return "hello";
}

2. The submitted domain name is inconsistent with the parameter name of the processing method

Submit data: http://localhost:8080/hello?username=jia

Treatment method:

//@Requestparam ("username"): the name of the domain submitted by username
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
    System.out.println(name);  //jia
    return "hello";
}

3. Submitted is an object

It is required that the submitted form field and the attribute name of the object are consistent, and the parameter can use the object

1. Entity class

public class User {
    private int id;
    private String name;
    private int age;
    //structure
    //get/set
    //tostring()
}

2. Submit data: http://localhost:8080/mvc04/user?name=jia&id=1&age=15

3. Treatment method:

  • Receive the parameters passed by the front-end user and judge the name of the parameter. If the name is directly on the method, it can be used directly
  • Suppose the parameter passed is a User object. Match the field name in the User object: ok if the name is consistent, otherwise null
@RequestMapping("/user")
public String user(User user){
    System.out.println(user);
    return "hello";
}

Background output: user {id = 1, name = 'jia', age=15}

Note: if an object is used, the parameter name passed by the front end must be consistent with the object name, otherwise it is null.

5.3 data display to front end

First: through ModelAndView

public class ControllerTest1 implements Controller {
 
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //Returns a model view object
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","ControllerTest1");
        mv.setViewName("test");
        return mv;
    }
}

The second is through ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
    //Encapsulates the data to be displayed in the view
    //Equivalent to req setAttribute("name",name);
    model.addAttribute("name",name);
    System.out.println(name);
    return "hello";
}

Third: through Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
    //Encapsulates the data to be displayed in the view
    //Equivalent to req setAttribute("name",name);
    model.addAttribute("msg",name);
    System.out.println(name);
    return "test";
}

Model has only a few methods, which are only suitable for storing data, simplifying novices' operation and understanding of model objects;

ModelMap inherits LinkedMap. In addition to implementing some of its own methods, ModelMap also inherits the methods and features of LinkedMap;

ModelAndView can store data, set the returned logical view, and control the jump of the display layer.

6. Garbled code problem

  1. The Post request is garbled, and the Get request is normal

    @Controller
    public class EncodingController {
    
        //Filter to solve garbled code
        @GetMapping("/e/t")
        //@PostMapping("/e/t") / / use Post to request garbled code, and get is normal
        public String test1(String name, Model model){
            model.addAttribute("msg", name);
            return "test1";
        }
    }
    
  2. Spring MVC provides us with a filter that can be used on the web Configuration in XML (judge whether it has been solved?)

    <!--to configure SpringMVC Random code filter-->
    <filter>
        <filter-name>encoding</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>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  3. Modify tomcat configuration file: set encoding

​ server.xml:

<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />		

4. Ultimate custom filter

package com.smile.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * Filter to solve all the garbled codes of get and post requests
 */
public class GenericEncodingFilter implements Filter {

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //Handle the character encoding of the response
        HttpServletResponse myResponse=(HttpServletResponse) response;
        myResponse.setContentType("text/html;charset=UTF-8");

        // Transformation into agreement related objects
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        // Enhanced request packaging
        HttpServletRequest myrequest = new MyRequest(httpServletRequest);
        chain.doFilter(myrequest, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

}

//Custom request object, wrapper class of HttpServletRequest
class MyRequest extends HttpServletRequestWrapper {

    private HttpServletRequest request;
    //Coded flag
    private boolean hasEncode;
    //Define a constructor that can be passed into the HttpServletRequest object to decorate it
    public MyRequest(HttpServletRequest request) {
        super(request);// super must write
        this.request = request;
    }

    // Override methods that need to be enhanced
    @Override
    public Map getParameterMap() {
        // Get request method first
        String method = request.getMethod();
        if (method.equalsIgnoreCase("post")) {
            // post request
            try {
                // Handle post garbled code
                request.setCharacterEncoding("utf-8");
                return request.getParameterMap();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else if (method.equalsIgnoreCase("get")) {
            // get request
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (!hasEncode) { // Ensure that the get manual encoding logic runs only once
                for (String parameterName : parameterMap.keySet()) {
                    String[] values = parameterMap.get(parameterName);
                    if (values != null) {
                        for (int i = 0; i < values.length; i++) {
                            try {
                                // Handle get garbled code
                                values[i] = new String(values[i]
                                        .getBytes("ISO-8859-1"), "utf-8");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                hasEncode = true;
            }
            return parameterMap;
        }
        return super.getParameterMap();
    }

    //Take a value
    @Override
    public String getParameter(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        if (values == null) {
            return null;
        }
        return values[0]; // Retrieve the first value of the parameter
    }

    //Take all values
    @Override
    public String[] getParameterValues(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        return values;
    }
}

Go to the web XML configuration

<!--Configure custom garbled filter-->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.smile.filter.GenericEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
6.1 JSON garbled code

Add in configuration file

<!--JSON Garbled problem configuration-->
<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

7JSON

The full name of json is JavaScript Object Notation, which is a lightweight data interaction format.

Front end JavaScript comes with JSON:

<script>
    //Write a js object
    var user ={
        name:"Mrs Jia",
        age:19,
        sex:"male"
    };
    console.log(user);
    //Convert js objects to json objects
    var json = JSON.stringify(user);
    console.log(json);
    console.log("===========")
    //Convert json to js object
    var parse = JSON.parse(json);
    console.log(parse);
</script>
7.1 Jackson
7.2 Fastjson

8 Ajax technology

  1. brief introduction
    AJAX = Asynchronous JavaScript and XML.
    AJAX is a technology that can update some web pages without reloading the whole web page.
    Ajax is not a new programming language, but a technology for creating better, faster and more interactive Web applications.
    Web pages using ajax technology can realize asynchronous local update through a small amount of data exchange in the background server
8.1 jquery.Ajax
  • The core of Ajax is the XMLHttpRequest object (XHR). XHR provides an interface for sending requests to the server and parsing server responses. Ability to get new data from the server asynchronously
  • Through the jQuery AJAX method, you can use HTTP Get and HTTP Post to request text, HTML, XML or JSON from a remote server - and you can load these external data directly into the selected elements of the web page
  • The essence of jQuery Ajax is XMLHttpRequest, which is encapsulated for easy calling
jQuery.ajax(...)
      Some parameters:
            url: Request address
            type: Request method, GET,POST(1.9.0 Later use method)
        	headers: Request header
            data: Data to send
    contentType: The content encoding type of the message to be sent to the server(default: "application/x-www-form-urlencoded; charset=UTF-8")
          async: Asynchronous
        timeout: Set request timeout (MS)
      beforeSend: Function executed before sending the request(overall situation)
        complete: Callback function executed after completion(overall situation)
        success: Callback function executed after success(overall situation)
          error: Callback function executed after failure(overall situation)
        accepts: Send the request to the server and tell the server the data type acceptable to the current client
        dataType: Converts the data returned by the server to the specified type
          "xml": Convert the content returned by the server into xml format
          "text": Convert the content returned by the server to normal text format
          "html": Convert the content returned by the server into normal text format and insert DOM If it contains JavaScript Tag, it will try to execute.
        "script": Try to treat the return value as JavaScript To execute, and then convert the content returned by the server into normal text format
          "json": Convert the content returned by the server into the corresponding JavaScript object
        "jsonp": JSONP Format use JSONP When calling a function as "myurl?callback=?" jQuery Will automatically replace ? Give the correct function name to execute the callback function

  1. Write an Ajax controller

    @Controller
    public class AjaxController {
    
       @RequestMapping("/a1")
       public void ajax1(String name , HttpServletResponse response) throws IOException {
           if ("admin".equals(name)){
               response.getWriter().print("true");
          }else{
               response.getWriter().print("false");
          }
      }
    
    }
    
  2. Write index JSP test

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
     <head>
       <title>$Title$</title>
      <%--<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>--%>
       <script src="${pageContext.request.contextPath}/statics/js/jquery-3.1.1.min.js"></script>
       <script>
           function a1(){
               $.post({
                   url:"${pageContext.request.contextPath}/a1",
                   data:{'name':$("#txtName").val()},
                   success:function (data,status) {
                       alert(data);
                       alert(status);
                  }
              });
          }
       </script>
     </head>
     <body>
    
    <%--onblur: Loss of focus trigger event--%>
    user name:<input type="text" id="txtName" οnblur="a1()"/>
    
     </body>
    </html>
    
8.2 spring MVC implementation, click query to add

User.java

package com.smile.controller.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
    private String sex;

}

Controller

@RequestMapping("/a2")
public List<User> ajax2(){
    List<User> list = new ArrayList<User>();
    list.add(new User("Zhang San",10,"male"));
    list.add(new User("Li Si",20,"female"));
    list.add(new User("Wang Wu",30,"male"));
    return list; //Due to the @ RestController annotation, convert the list to json format and return
}

test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<input type="button" id="btn" value="get data"/>
<table width="80%" align="center">
    <tr>
        <td>full name</td>
        <td>Age</td>
        <td>Gender</td>
    </tr>
    <tbody id="content">
    </tbody>
</table>

<script src="${pageContext.request.contextPath}/static/js/jquery-3.5.1.js"></script>
<script>

    $(function () {
        $("#btn").click(function () {
            $.post("${pageContext.request.contextPath}/a2",function (data) {
                console.log(data)
                var html="";
                for (var i = 0; i <data.length ; i++) {
                    html+= "<tr>" +
                        "<td>" + data[i].name + "</td>" +
                        "<td>" + data[i].age + "</td>" +
                        "<td>" + data[i].sex + "</td>" +
                        "</tr>"
                }
                $("#content").html(html);
            });
        })
    })
</script>
</body>
</html>
8.3 verification prompt

controller

@RequestMapping("/a3")
public String ajax3(String name,String pwd){
    String msg = "";
    //There is data in the simulation database
    if (name!=null){
        if ("admin".equals(name)){
            msg = "OK";
        }else {
            msg = "User name input error";
        }
    }
    if (pwd!=null){
        if ("123456".equals(pwd)){
            msg = "OK";
        }else {
            msg = "Incorrect password input";
        }
    }
    return msg; //Due to the @ RestController annotation, msg is converted to json format and returned
}

Front end page: json format filter needs to be configured

<%--
  Created by IntelliJ IDEA.
  User: FURONG
  Date: 2021/12/8
  Time: 12:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>User name verification</title>
    <script src="${pageContext.request.contextPath}/static/js/jquery-3.5.1.js"></script>

    <script>
        function a1(){
            $.post({
                url:"${pageContext.request.contextPath}/a3",
                data:{'name':$("#name").val()},
                success:function (data) {
                    if (data.toString()=='OK'){
                        $("#userInfo").css("color","green");
                    }else {
                        $("#userInfo").css("color","red");
                    }
                    $("#userInfo").html(data);
                }
            });
        }
        function a2(){
            $.post({
                url:"${pageContext.request.contextPath}/a3",
                data:{'pwd':$("#pwd").val()},
                success:function (data) {
                    if (data.toString()=='OK'){
                        $("#pwdInfo").css("color","green");
                    }else {
                        $("#pwdInfo").css("color","red");
                    }
                    $("#pwdInfo").html(data);
                }
            });
        }
    </script>
</head>
<body>

<p>
    user name:<input type="text" id="name" οnblur="a1()"/>
    <span id="userInfo"></span>
</p>
<p>
    password:<input type="text" id="pwd" οnblur="a2()"/>
    <span id="pwdInfo"></span>
</p>

</body>
</html>

JSON random code filtering:

<!--JSON Garbled problem configuration-->
<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

9 spring MVC interceptor

9.1 introduction

The processor interceptor of spring MVC is similar to the Filter in Servlet development, which is used to preprocess and post process the processor. Developers can define some interceptors to implement specific functions.

  • filter
    • Part of the servlet specification that can be used by any java web project
    • After / * is configured in URL pattern, all resources to be accessed can be intercepted
  • Interceptor
    • The interceptor is the spring MVC framework's own. It can only be used by projects that use the spring MVC framework
    • The interceptor will only intercept the accessed controller methods. If the accessed is jsp/html/css/image/js, it will not intercept
9.2 custom interceptors

To customize the interceptor, you must implement the HandlerInterceptor interface.

1. Create a Moudule, springmvc-07-Interceptor, and add web support

2. Configure web XML and spring MVC servlet XML file

3. Write an interceptor

package com.smile.config;

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

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

public class MyInterceptor implements HandlerInterceptor {

    //Before the method of request processing is executed, it is configured in the configuration file
    //If true is returned, execute the next interceptor
    //If false is returned, the next interceptor is not executed
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    /**
     * The following two can be treated as logs
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    //Executed after the request processing method is executed
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
    //After the dispatcher servlet is processed, it is executed and cleaned up
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
<!--About interceptor configuration springMvc configuration file-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--/** Include paths and their sub paths-->
        <!--/admin/* Intercepting is/admin/add Wait, this , /admin/add/user Will not be intercepted-->
        <!--/admin/** Intercepting is/admin/All under-->
        <mvc:mapping path="/**"/>
        <!--bean The interceptor is configured-->
        <bean class="com.smile.config.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
9.2 interceptor login judgment verification

Realization idea

1. There is a login page. You need to write a controller access page.

2. The login page has an action to submit a form. It needs to be processed in the controller. Determine whether the user name and password are correct. If correct, write user information to the session. Return to login success.

3. Intercept the user's request and judge whether the user logs in. If the user has logged in. Release. If the user does not log in, jump to the login page

Sign in:

<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Login page</h1>
    <form action="${pageContext.request.contextPath}/user/login" method="post">
        user name: <input type="text" name="username" />
        password:   <input type="text" name="password" />
        <input type="submit" value="Submit">
    </form>
<textarea>stay web-inf All resources or pages under can only be accessed through controller perhaps servlet Visit</textarea>
</body>
</html>

Custom Interceptor: it needs to be configured in the configuration file:

<mvc:interceptor>
    <!--Include all requests below this request-->
    <mvc:mapping path="/user/**"/>
    <!--bean The interceptor is configured-->
    <bean class="com.smile.config.LoginInterceptor"/>
</mvc:interceptor>
package com.smile.config;

import org.springframework.web.servlet.HandlerInterceptor;

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

public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // If it is a landing page, release it
        System.out.println("uri: " + request.getRequestURI());
        if (request.getRequestURI().contains("login")) {
            System.out.println(request.getRequestURI());
            return true;
        }

        HttpSession session = request.getSession();

        // Release if the user has logged in
        if(session.getAttribute("userLoginInfo") != null) {
            return true;
        }

        // The user does not log in and jumps to the login page
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }
}

controller layer:

package com.smile.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class LoginController {

    @RequestMapping("/login")
    public String login(HttpSession session, String username, String password, Model model){
        System.out.println("login==>"+username);
        model.addAttribute("userLoginInfo",username);
        //Store the user's information in the session
        session.setAttribute("userLoginInfo",username);
        return "main";
    }

    @RequestMapping("/main")
    public String index(){
        return "main";
    }

    @RequestMapping("/gologin")
    public String gologin(){
        return "login";
    }

    //cancellation
    @RequestMapping("/goout")
    public String goout(HttpSession session){
        session.removeAttribute("userLoginInfo");  //remove
//        session.invalidate(); // Destroy this session
        return "login";
    }

}

Log off after success:

<%--
  Created by IntelliJ IDEA.
  User: FURONG
  Date: 2021/12/8
  Time: 15:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>home page</h1>

    <h3>
        <span>${userLoginInfo}</span>
    </h3>

    <a href="${pageContext.request.contextPath}/user/goout">cancellation</a>
</body>
</html>

10 file upload and download:

File upload is one of the most common functions in project development. Spring MVC can well support file upload, but MultipartResolver is not installed in the spring MVC context by default, so it cannot handle file upload by default. If you want to use spring's file upload function, you need to configure MultipartResolver in the context.

Front end form requirements: in order to upload files, the method of the form must be set to POST and the enctype must be set to multipart / form data. Only in this case, the browser will send the file selected by the user to the server as binary data;

Give a detailed description of the enctype attribute in the form:

  • Application / x-www = form urlencoded: by default, only the value attribute value in the form field is processed. Forms with this encoding method will process the value in the form field into URL encoding.
  • Multipart / form data: this encoding method will process form data in the form of binary stream. This encoding method will also encapsulate the contents of the file specified in the file field into the request parameters, and will not encode characters.
  • text/plain: except for converting spaces into "+" signs, other characters are not encoded. This method is applicable to sending mail directly through forms
<form action="" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit">
</form>

Once the enctype is set to multipart / form data, the browser will process the form data in the form of binary stream, and the processing of file upload involves parsing the original HTTP response on the server side. In 2003, the Apache Software Foundation released the open source Commons FileUpload component, which soon became the best choice for Servlet/JSP programmers to upload files.

  • Servlet3. The 0 specification has provided a method to handle file upload, but this upload needs to be completed in the servlet.
  • Spring MVC provides a simpler encapsulation.
  • Spring MVC provides direct support for file upload, which is implemented with the plug and play MultipartResolver.
  • Spring MVC implements a MultipartResolver implementation class using Apache Commons FileUpload Technology:
  • CommonsMultipartResolver. Therefore, the file upload of spring MVC also depends on the component of Apache Commons FileUpload.
10.1 file upload

1. Import the jar package uploaded by the file, commons file upload, and Maven will automatically help us import his dependent package commons IO package;

<!--File upload-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
<!--servlet-api Import a later version of-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

2. Configuration bean: multipartResolver

[note!!! The id of this bena must be: multipartResolver, otherwise an error of 400 will be reported when uploading the file! I've planted a pit here, and I'll teach you a lesson!]

<!--File upload configuration-->
<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- The encoding format of the request must be and jSP of pageEncoding Property is consistent so that the contents of the form can be read correctly. The default is ISO-8859-1 -->
    <property name="defaultEncoding" value="utf-8"/>
    <!-- Maximum upload file size, in bytes (10485760)=10M) -->
    <property name="maxUploadSize" value="10485760"/>
    <property name="maxInMemorySize" value="40960"/>
</bean>

Common methods of CommonsMultipartFile:

  • String getOriginalFilename(): get the original name of the uploaded file
  • InputStream getInputStream(): get file stream
  • void transferTo(File dest): save the uploaded file to a directory file

Let's actually test it

3. Write front page

<form action="/upload" enctype="multipart/form-data" method="post">
  <input type="file" name="file"/>
  <input type="submit" value="upload">
</form>

4,Controller

package com.kuang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;

@Controller
public class FileController {
    //@RequestParam("file") encapsulates the file obtained by the name=file control into a CommonsMultipartFile object
    //If you upload CommonsMultipartFile in batch, it can be an array
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //Get file name: file getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //If the file name is empty, go back to the home page directly!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("Upload file name : "+uploadFileName);

        //Upload path save settings
        String path = request.getServletContext().getRealPath("/upload");
        //If the path does not exist, create one
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("Upload file storage address:"+realPath);

        InputStream is = file.getInputStream(); //File input stream
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //File output stream

        //Read write
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }
}

5. Test upload file, OK!

10.2 file download

1. Set response header

2. Read file – InputStream

3. Write out file – OutputStream

4. Perform operation

5. Close flow (first on then off)

Code implementation:

@RequestMapping(value="/download")
public String downloads(HttpServletResponse response ,HttpServletRequest request) throws Exception{
    //Address of the picture to download
    String  path = request.getServletContext().getRealPath("/upload");
    String  fileName = "Basic grammar.jpg";

    //1. Set response header
    response.reset(); //Set the page not to be cached, and clear the buffer
    response.setCharacterEncoding("UTF-8"); //Character encoding
    response.setContentType("multipart/form-data"); //Binary transmission data
    //Set response header
    response.setHeader("Content-Disposition",
            "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));

    File file = new File(path,fileName);
    //2. Read file -- input stream
    InputStream input=new FileInputStream(file);
    //3. Write out file -- output stream
    OutputStream out = response.getOutputStream();

    byte[] buff =new byte[1024];
    int index=0;s
    //4. Perform a write out operation
    while((index= input.read(buff))!= -1){
        out.write(buff, 0, index);
        out.flush();
    }
    out.close();
    input.close();
    return null;
}

front end

<a href="/download">Click download</a>

Question:

1. 404 error:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-bdFbHM2R-1640585948390)(E:\Typroa notes \ SpringMVC.assets\image-20211204131454429.png)]

Check for lib packages

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-uFzHBWAy-1640585948391)(E:\Typroa notes \ SpringMVC.assets\image-20211204131405731.png)]

Solution:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-6562fti-1640585948392) (E: \ typroa notes \ SpringMVC.assets\image-20211204131723254.png)]

2. Import of lib in idea failed

In POM Add the following code to XML:

<!--maven Resource filtering problem-->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            
            //be careful
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

response.setContentType(“multipart/form-data”); // Binary transmission data
//Set response header
response.setHeader("Content-Disposition",
"attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));

File file = new File(path,fileName);
//2. Read file -- input stream
InputStream input=new FileInputStream(file);
//3. Write out file -- output stream
OutputStream out = response.getOutputStream();

byte[] buff =new byte[1024];
int index=0;s
//4. Perform a write out operation
while((index= input.read(buff))!= -1){
    out.write(buff, 0, index);
    out.flush();
}
out.close();
input.close();
return null;

}

front end

```php
<a href="/download">Click download</a>

Question:

1. 404 error:

[external chain picture transferring... (img-bdFbHM2R-1640585948390)]

Check for lib packages

[external chain picture transferring... (IMG ufzhbway-1640585948391)]

Solution:

[external chain picture transferring... (img-6562fti-1640585948392)]

2. Import of lib in idea failed

In POM Add the following code to XML:

<!--maven Resource filtering problem-->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            
            //be careful
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

Topics: Java Spring mvc