Execution process, Controller, RestFul style, data processing and jump of Spring MVC

Spring MVC-1

summary

Spring MVC is a part of the Spring Framework. It is a lightweight web framework based on java to implement mvv.

View official documents: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc

Why should we learn spring MVC?

Features of Spring MVC:

  1. Lightweight, easy to learn
  2. Funny, request response based MVC framework
  3. Good compatibility with Spring and seamless combination
  4. Convention over configuration
  5. Powerful functions: RESTful, data validation, formatting, localization, theme, etc
  6. Concise and flexible

Spring's web framework revolves around the dispatcher servlet

The dispatcher servlet is used to distribute requests to different processors. Starting from spring 2.5, users using Java 5 or above can develop based on annotations, which is very concise.

The most important point is that there are many people and companies

Central processor

Spring's web framework revolves around the dispatcher servlet. The dispatcher servlet is used to distribute requests to different processors. Starting from spring 2.5, users using Java 5 or above can adopt annotation based controller declaration

Like many other MVC frameworks, the Spring MVC framework is request driven and provides requests and other functions around a central Servlet. The dispatcher Servlet is an actual Servlet (it inherits from the HttpServlet base class)

Briefly analyze the implementation process

1. 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.

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

3. 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.

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

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

6. The Handler lets the specific Controller execute.

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

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

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

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

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

12. The final view is presented to the user.

Spring MVC program

Configuration version

  1. Create a new project, spring spring MVC hellomvc, and add web support!
  2. Confirm that the dependency of spring MVC is imported!
  3. Configure web.xml and register dispatcherservlet (pay attention to the version)
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
  <display-name>Archetype Created Web Application</display-name>

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

  <!--Match all requests (including.jsp)-->
  <!--Match all requests (excluding.jsp)-->
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
  1. Write the spring MVC configuration file! Name: SpringMVC-servlet.xml: [servletname] - servlet.xml

    The name requirements here are in accordance with the official

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

    
</beans>
  1. Add process mapper
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
  1. Add processor adapter
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
  1. Add view parser
<!--view resolver :DispatcherServlet Give it to him ModelAndView-->
    <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>
  1. Write the operation business Controller, either implement the Controller interface or add annotations; you need to return a ModelAndView, load data and seal the view;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 14:34
 */
//Note: let's import the Controller interface first
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
        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;
    }
}
  1. Give your class to the spring IOC container and register the bean
<!--Handler-->
    <bean id="/hello" class="com.gd.controller.HelloController"/>
  1. Write the jsp page to jump to, display the data stored in ModelandView, and our normal page
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>${msg}</h2>
</body>
</html>
  1. catalogue

  • be careful

    • Add web framework support in the following ways

    • To add the directory lib

    • lib directory to add library files

    • All dependencies of the project should be added

Annotated version

  1. Create a new project, spring spring MVC annotation. Add web support!
  2. Since Maven may have the problem of resource filtering, we will improve the configuration
<build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
  1. Introduce relevant dependencies in pom.xml file: mainly Spring framework core library, Spring MVC, servlet, JSTL, etc. we have introduced them in parent dependencies!
  2. Configure 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 servlet-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--Specified by initialization parameters SpringMVC The location of the configuration file is associated-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>       <!-- Start sequence: the smaller the number, the earlier the start -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--All requests will be rejected springmvc intercept -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

be careful:

  1. Pay attention to the version of web.xml. Keep the latest version!

  2. Register DispatcherServlet

  3. Associated spring MVC configuration file

  4. The startup level is 1

  5. The mapping path is / [do not use / *, it will 404]

    /Difference from / *: < URL pattern > / < / url pattern > will not match. jsp, but only for the request we write; that is:. jsp will not enter the spring DispatcherServlet class. < URL pattern > / < / url pattern > will match. jsp, and it will enter the spring DispatcherServlet class again when returning to the jsp view, resulting in no corresponding controller, so a 404 error is reported.

  6. Add Spring MVC configuration file

Add the springmvc-servlet.xml configuration file in the resource directory. The configuration form is basically similar to the Spring container configuration. In order to support annotation based IOC, the function of automatic package scanning is set. The specific configuration information is as follows:

<?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">
    <!--
    <context:component-scan base-package="com.gd.controller"/>
    <mvc:default-servlet-handler />
    <mvc:annotation-driven />
	-->

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

be careful:

  • Make IOC comments effective
  • Static resource filtering: HTML, JS, CSS, pictures, videos
  • Annotation driven MVC
  • Configure view parser

In the view parser, we store all 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.

  1. Create Controller

Write a Java control class: com.gd.controller.HelloController. Pay attention to the coding specification

package com.gd.controller;

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

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 21:05
 */
@Controller
//@RequestMapping("/hello")
public class HelloController {

    //localhost:8080//hello/h1
    @GetMapping("/h1")
    public String hello(Model model){
        //Encapsulate data
        model.addAttribute("msg","Hello,SpringMVCAnnotation");
        return "hello"; //Will be processed by the view parser
    }
}
  • @Controller This is to enable the Spring IOC container to be automatically scanned during initialization;
  • @RequestMapping It is to map the request path. Here, because there are mappings on classes and methods, the access should be / hello/h1;
  • The purpose of declaring Model type parameters in the method is to bring the data in the Action to the view;
  • The result returned by the method is the name of the view Hello, plus the prefix and suffix in the configuration file to become WEB-INF/jsp/hello.jsp.
  1. Create view layer

Create hello.jsp in the WEB-INF/ jsp directory. The view can directly take out and display the information brought back from the Controller; You can retrieve the values or objects stored in the Model through EL representation

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>
  1. Configure Tomcat run

Configure Tomcat, start the server and access the corresponding request path!

  1. catalog:

Controller and RestFul

Controller controller

  • The complex controller provides the behavior of accessing the application program, which is usually implemented by interface definition or annotation definition.
  • The controller is responsible for parsing the user's request and transforming it into a model.
  • In Spring MVC, a controller class can contain multiple methods
  • In Spring MVC, there are many ways to configure the Controller

Implement Controller interface

Controller is an interface. Under the org.springframework.web.servlet.mvc package, there is only one method in the interface

//The class implementing the interface obtains the controller function
public interface Controller {
   //Process the request and return a model and view object
   ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
test
  1. Create a new Moudle, spring spring MV controller. Copy the annotation just now and let's operate!
    • Delete HelloController
    • mvc's configuration file leaves only the view parser!
  2. Write a Controller class, ControllerTest1
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

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

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 21:50
 */
//Define controller
//Note: do not import the wrong package, implement the Controller interface and rewrite the method;
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","Test1Controller");
        mv.setViewName("test");
        return mv;
    }
}
  1. Write the front-end test.jsp. Note that it is written in the WEB-INF/jsp directory, corresponding to our view parser
  • springmvc-servlet.xml
<bean name="/t1" class="com.gd.controller.ControllerTest1"/>
  • test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${msg}
</body>
</html>
explain
  • It is an old method to implement the interface Controller and define the Controller
  • The disadvantages are: there is only one method in a Controller. If you want multiple methods, you need to define multiple controllers; The way of definition is troublesome

Using annotations @Controller

  • @Controller The annotation type is used to declare that the instance of the Spring class is a controller (another three annotations were mentioned when talking about IOC);
  • Spring can use the scanning mechanism to find all annotation based controller classes in the application. In order to ensure that spring can find your controller, you need to declare component scanning in the configuration file.
<!-- Automatically scan the specified package, and submit all the following annotation classes to IOC Container management -->
<context:component-scan base-package="com.gd.controller"/>
test
  • Add a ControllerTest2 class and implement it with annotations
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 22:01
 */
@Controller
//Represents that this class will be taken over by Spring,
// If the return value of all methods in the annotated class is String,
// If there is a specific page that can jump, it will be parsed by the view parser
public class ControllerTest2 {
    //Map access path
    @RequestMapping("/t2")
    public String index(Model model){
        //Spring MVC will automatically instantiate a Model object to pass values to the view
        model.addAttribute("msg", "ControllerTest2");
        //Return to view location
        return "test";
    }
    
    @RequestMapping("/t3")
    public String index2(Model model){
        //Spring MVC will automatically instantiate a Model object to pass values to the view
        model.addAttribute("msg", "ControllerTest3");
        //Return to view location
        return "test";
    }
}
characteristic
  • It can be found that both of our requests can point to a view, but the results of the page results are different. It can be seen from here that the view is reused, and there is a weak coupling relationship between the controller and the view.

Annotation is the most commonly used method!

@RequestMapping

  • @RequestMapping Annotations are used to map URLs to a controller class or a specific handler method. Can be used on classes or methods. Used on a class to indicate that all methods in the class that respond to requests take this address as the parent path.
  • In order to test the conclusion more accurately, we can add a project name to test myweb
  • Annotate only on Methods
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 22:19
 */
@Controller
public class ControllerTest3 {
    @RequestMapping("/h1")
    public String test(){
        return "test";
    }
}

Access path: http://localhost:8080 /Project name / h1\

  • Annotate classes and methods at the same time (not recommended)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 22:19
 */
@Controller
@RequestMapping("/admin")
public class ControllerTest3 {
    @RequestMapping("/h1")
    public String test(){
        return "test";
    }
}

Access path: http://localhost:8080 /The project name is / admin /h1. You need to specify the path of the class first, and then the path of the method

RestFul style

concept

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 can be more concise, more hierarchical, and easier to implement caching and other mechanisms.

function

  • Resources: all things on the Internet can be abstracted as resources

  • Resource operation: use POST, DELETE, PUT and GET to operate resources using different methods.

  • Add, delete, modify and query respectively.

Operating resources in traditional ways

Different effects can be achieved through different parameters! Single method, post and get

http://localhost:8080/item/queryItem.action?id=1 Query, GET

http://localhost:8080/item/saveItem.action New, POST

http://localhost:8080/item/updateItem.action Update, POST

http://localhost:8080/item/deleteItem.action?id=1 Delete, GET or POST

Operating resources with RESTful

Different effects can be achieved through different request methods! As follows: the request address is the same, but the function can be different!

http://localhost:8080/item/1 Query, GET

http://localhost:8080/item New, POST

http://localhost:8080/item Update, PUT

http://localhost:8080/item/1 DELETE

Learning test

  1. It can be used in Spring MVC @PathVariable Annotation to bind the value of the method parameter to a URI template variable
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 22:32
 */
@Controller
public class RestController {

    //customary: http://localhost:8080/add?a=1&b=2
    //RestFul:http://localhost:8080/add/a/b
    @RequestMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a,@PathVariable String b, Model model){
        String res = a + b;
        model.addAttribute("msg","The result is:"+res);
        return "test";
    }
}
  1. test result

Use the method property to specify the request type

It is used to constrain the type of request and narrow the request range. Specify the type of request predicate, such as GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE, etc

  • test
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @author zhuxianglong
 * @version 1.0
 * @date 2021/9/22 22:32
 */
@Controller
public class RestController {

    //customary: http://localhost:8080/add?a=1&b=2
    //RestFul:http://localhost:8080/add/a/b
    //@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
    @GetMapping("/add/{a}/{b}")
    //@DeleteMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a,@PathVariable String b, Model model){
        String res = a + b;
        model.addAttribute("msg","The result is:"+res);
        return "test";
    }
}
Summary

Spring MVC @RequestMapping Annotate methods that can handle HTTP requests, such as GET, PUT, POST, DELETE, and PATCH.

All address bar requests will be of HTTP GET type by default.

  • Method level annotation variants are as follows: combined annotation
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
  • @GetMapping It is a combined annotation, which will be used more at ordinary times!

  • What it plays is @RequestMapping (method =RequestMethod.GET).

Data processing and jump

Result jump mode

ModelAndView

Set the ModelAndView object and jump to the specified page according to the name of the view and the view parser

Page: {view parser prefix} + viewName + {view parser suffix}

<!-- view resolver  -->
<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>

Corresponding controller class

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;
  }
}

ServletAPI

By setting the servlet API, no view parser is required

1. Output through HttpServletResponse

2. Redirection via HttpServletResponse

3. Forwarding through HttpServletResponse

@Controller
public class ResultGo {
   @RequestMapping("/result/t1")
   public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
       rsp.getWriter().println("Hello,Spring BY servlet API");
  }
   @RequestMapping("/result/t2")
   public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
       rsp.sendRedirect("/index.jsp");
  }
   @RequestMapping("/result/t3")
   public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
       //forward
       req.setAttribute("msg","/result/t3");
       req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
  }
}

SpringMVC

  • Forwarding and redirection via spring MVC - no view parser required

Before testing, you need to comment out the view parser

@Controller
public class ResultSpringMVC {
   @RequestMapping("/rsm/t1")
   public String test1(){
       //forward
       return "/index.jsp";
  }
   @RequestMapping("/rsm/t2")
   public String test2(){
       //Forward two
       return "forward:/index.jsp";
  }
   @RequestMapping("/rsm/t3")
   public String test3(){
       //redirect
       return "redirect:/index.jsp";
  }
}

Forwarding and redirection through spring MVC - view parser

Redirection does not require a view parser. Its essence is to re request a new place, so pay attention to the path problem

You can redirect to another request implementation

@Controller
public class ResultSpringMVC2 {
   @RequestMapping("/rsm2/t1")
   public String test1(){
       //forward
       return "test";
  }
   @RequestMapping("/rsm2/t2")
   public String test2(){
       //redirect
       return "redirect:/index.jsp";
       //return "redirect:hello.do"; //hello.do is another request/
  }
}

data processing

Process submitted data

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

    Submit data: http://localhost:8080/hello?name=zhuxianglong

    Treatment method:

    @RequestMapping("/hello")
    public String hello(String name){
       System.out.println(name);
       return "hello";
    }
    
  2. The submitted domain name is inconsistent with the parameter name of the processing method

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

    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);
       return "hello";
    }
    

    Background output: zhuxianglong

  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=zhuxianglong&id=1&age=18

    3. Treatment method:

      @RequestMapping("/user")
      public String user(User user){
         System.out.println(user);
         return "hello";
      }
      

      Background output: user {id = 1, name = 'zhuxianglong', age=18}

      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.

Data display to front end

  1. 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;
      }
    }
    
  2. 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";
    }
    
  3. 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";
    }
    

    contrast:

    For novices, the simple difference is:

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

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

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

      Of course, more future development is more about performance and optimization, so it can't be limited to this understanding.

Garbled code problem

  1. Test steps:

    <!--We can write a submission form on the home page-->
    <form action="/e/t" method="post">
     <input type="text" name="name">
     <input type="submit">
    </form>
    
  2. Write the corresponding processing class in the background

    @Controller
    public class Encoding {
       @PostMapping("/e/t")
       public String test(Model model,String name){
           model.addAttribute("msg",name); //Gets the value of the form submission
           return "test"; //Jump to the test page and display the entered value
      }
    }
    
  3. Input Chinese test, found garbled code

    It has to be said that the problem of garbled code is very common in our development, and it is also a big problem for our program ape!

    In the past, the problem of garbled code was solved through filters, and spring MVC provided us with a filter that can be configured in web.xml

    The xml file has been modified. You need to restart the server!

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

    However, we found that in some extreme cases, this filter does not support get well

Treatment method:

  1. Modify tomcat configuration file: set code!

    <Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
              connectionTimeout="20000"
              redirectPort="8443" />
    
  2. Custom 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 {
       @Override
       public void destroy() {
      }
       @Override
       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);
      }
       @Override
       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;
      }
    }
    

    This is also written by some great gods on the Internet. Generally, the default garbled code processing of spring MVC can be well solved!

Then configure this filter in web.xml!

The problem of garbled code needs more attention at ordinary times. The unified coding UTF-8 should be set wherever possible!

Keywords: Java Spring RESTful mvc

Added by spheonix on Wed, 22 Sep 2021 19:22:59 +0300