Detailed Explanation of SpringMVC (Super Comprehensive)

Table of contents

1. Introduction to SpringMvc

1. Review the MVC pattern

1.1 Concept

MVC design pattern generally refers to the MVC framework, M (Model) refers to the data model layer, V (View) refers to the view layer, and C (Controller) refers to the control layer. The purpose of using MVC is to separate the implementation codes of M and V, so that the same program can have different expressions. Among them, the definition of View is relatively clear, which is the user interface.

​ In the development of Web projects, it is very important to be able to respond to user requests in a timely and correct manner. The user clicks a URL path on the web page, which is equivalent to the user sending a request to the web server. After obtaining the request, how to parse the user's input, execute relevant processing logic, and finally jump to the correct page to display the feedback result, these tasks are often completed by the control layer (Controller).

​ During the request process, the user's information is encapsulated in the User entity class, which belongs to the data model layer (Model) in the Web project.

​ In the request display stage, the redirected result webpage belongs to the view layer (View).

​ Like this, the control layer is responsible for the interaction between the foreground and the background, the data model layer encapsulates the user's input/output data, and the view layer selects the appropriate view to display the final execution result. Such a hierarchical software development and processing flow is called MVC pattern.

​ When learning Servlet and JSP development, JavaBean is equivalent to Model, Servlet is equivalent to Controller, and JSP is equivalent to View.

Summarized as follows:

  • View layer (View): Responsible for formatting data and presenting them to users, including data display, user interaction, data validation, interface design and other functions.
  • Control layer (Controller): responsible for receiving and forwarding the request, after processing the request, specifying the view and sending the response result to the client.
  • Data model layer (Model): The model object has the most processing tasks and is the main part of the application. It is responsible for the processing of data logic (business rules) and the realization of data operations (ie, accessing data in the database).

1.2 Advantages and disadvantages

​ Anything has pros and cons, let's take a look at the pros and cons of MVC.

1.2.1 Advantages

  • Multiple views share a model, greatly improving code reusability
  • The three modules of MVC are independent of each other, loosely coupled architecture
  • Controllers increase application flexibility and configurability
  • Conducive to software engineering management

In short, we can finally create a perfect architecture of loose coupling + high reusability + high applicability through the MVC design pattern.

1.2.2 Disadvantages

  • The principle is complex
  • Increased complexity of system structure and implementation
  • Views have inefficient access to model data

2. The concept of Spring MVC

1. Concept

  • Spring MVC is a lightweight Web development framework based on the MVC design pattern provided by Spring, which is essentially equivalent to Servlet.
  • Spring MVC is the most clearly structured implementation of Servlet+JSP+JavaBean.
  • Since Spring MVC itself is part of the Spring framework, it can be said that it is seamlessly integrated with the Spring framework. It has inherent advantages in terms of performance, and is the most mainstream web development framework and the most popular development skill in the industry today.
  • In the Spring MVC framework, the Controller replaces the Servlet to assume the responsibility of the controller, which is used to receive the request, call the corresponding Model for processing, and return the processing result after the processor completes the business processing. The Controller calls the corresponding View and renders the processing result, and finally the client gets the response information.
  • Annotation-driven and RESTful support for Spring MVC.

2. Advantages

  • Clear role division, Spring MVC provides a very clear role division in terms of Model, View and Controller. These three aspects really perform their duties and are responsible for each.
  • Flexible configuration function, you can configure the class as a Bean through XML.
  • A large number of controller interfaces and implementation classes are provided. Developers can use the controller implementation classes provided by Spring, or implement controller interfaces by themselves.
  • It really has nothing to do with the implementation of the View layer. It does not force developers to use JSP, but can use technologies such as Velocity and FreeMarker according to project requirements.
  • Internationalization support
  • programming to interface
  • Seamless integration with Spring framework

3. The first Spring MVC program

3.1 Steps to use

3.1.1 Create a web application and import dependencies

<properties>
    <!-- spring版本号 -->
    <spring.version>4.0.2.RELEASE</spring.version>
    <!-- log4j日志文件管理包版本 -->
    <slf4j.version>1.7.7</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
  </properties>
  <!--依赖-->
  <dependencies>
    <!-- junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <!-- JSTL标签类 -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <!-- servlet依赖的jar包start -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
    </dependency>
    <!-- 映入JSON -->
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-core-asl</artifactId>
      <version>1.9.4</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>1.9.4</version>
    </dependency>
    <!-- spring核心包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- 日志 -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <!-- 格式化对象,方便输出日志 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.1.41</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <!--lombok-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2.2</version>
    </dependency>
  </dependencies>
  <build>
    <!--resources配置解决mybatis的mapperXml配置在java路径不被扫描的问题 -->
    <resources>
      <resource>
        <directory>src/main/java</directory>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <!-- 跳过测试 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <skipTests>true</skipTests>
        </configuration>
      </plugin>
    </plugins>
  </build>

3.1.2 Spring MVC configuration

​ Spring MVC is based on Servlet, and DispatcherServlet is the core of the entire Spring MVC framework, mainly responsible for intercepting requests and dispatching them to corresponding processors for processing. So to configure Spring MVC, you must first define DispatcherServlet. As with all servlets, the user must be configured in web.xml.

Create java and resource directories under the main directory.

3.1.2.1 Define DispatcherServlet (web.xml)
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <!-- 部署 DispatcherServlet -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:config/springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
    <!--支持异步处理-->
    <async-supported>true</async-supported>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

Precautions:

  1. When Spring MVC is initialized, it will look for configuration files in the WEB-INF directory of the application. The naming rule of the configuration files is "servletName-servlet.xml", such as springmvc-servlet.xml.
  2. You can also store the Spring MVC configuration file anywhere in the application directory, but you need to use the init-param element of the servlet to load the configuration file, and specify the location of the Spring MVC configuration file through the contextConfigLocation parameter.
<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
3.1.2.2 Creating Controllers

Create the com.hqyj.cl.controller package in the src directory, and create two traditional-style controller classes (implementing the Controller interface) in the package, RegisterController and LoginController, to handle the "registration" and "login" hyperlinks on the home page respectively request. Controller is the controller interface, and there is only one method handleRequest in the interface, which is used to process requests and return ModelAndView.

  1. LoginController
public class LoginController implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest arg0,
                                      HttpServletResponse arg1) throws Exception {
    
    
        return new ModelAndView("/WEB-INF/jsp/login.jsp");   //注意文件路径是否在WEB-INF文件夹中
    }
}
  1. RegisterController
public class RegisterController implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest arg0,
                                      HttpServletResponse arg1) throws Exception {
    
    
        return new ModelAndView("/WEB-INF/jsp/register.jsp");
    }
}
3.1.2.3 Create Spring MVC configuration file

Create the springmvc-servlet.xml file

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

    <!-- LoginController控制器类,映射到"/login" -->
    <bean name="/login"
          class="com.hqyj.cl.controller.LoginController"/>
    <!-- LoginController控制器类,映射到"/register" -->
    <bean name="/register"
          class="com.hqyj.cl.controller.RegisterController"/>
</beans>
3.1.2.4 Create page
  1. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>Hello World!</h2>
未注册的用户,请
<a href="${pageContext.request.contextPath}/register"> 注册</a>!
<br /> 已注册的用户,去
<a href="${pageContext.request.contextPath}/login"> 登录</a>!
</body>
</html>
  1. login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
login
</body>
</html>
  1. register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>register</title>
</head>
<body>
register
</body>
</html>
3.1.2.5 Configuring the Tomcat server

slightly

3.1.2.6 Testing

slightly

2. Spring MVC View Resolver (ViewResolver)

View Resolver (ViewResolver) is an important part of Spring MVC, responsible for resolving logical view names into specific view objects.

1. Commonly used view analysis classes

1.1 URLBasedViewResolver

1.1.1 Overview

​ UrlBasedViewResolver is a simple implementation of ViewResolver, which mainly provides a way of splicing URLs to resolve views.

1.1.2 Principle

​ UrlBasedViewResolver specifies the prefix through the prefix attribute, and the suffix attribute specifies the suffix. When the ModelAndView object returns a specific View name, it will concatenate the prefix prefix and suffix suffix with the specific view name to obtain a specific loading path of the view resource file, thereby loading the real view file and feeding it back to the user.

1.1.3 Configuration

​ To use UrlBasedViewResolver, in addition to configuring the prefix and suffix attributes, you also need to configure "viewClass" to indicate which view to resolve. The sample code is as follows

<!--配置视图解析器之URLBasedViewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <!--不能省略-->
    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>
1.1.3.1 Description
  • The above view resolver is configured with two attributes, prefix and suffix, which shortens the view path. The view paths of the RegisterController and LoginController controller classes in the first Spring MVC program only need to provide register and login, and the view resolver will automatically add the prefix and suffix, which is resolved here as /WEB-INF/jsp/register.jsp and /WEB-INF/jsp/login.jsp.
  • When using UrlBasedViewResolver, you must specify the attribute viewClass to indicate which view to resolve. Generally, InternalResourceView is used more often to display jsp, but when we use JSTL, we must use JstlView.
  • The content stored in the /WEB-INF/ directory cannot be obtained directly through the request request, so for security reasons, the jsp file is usually placed in the WEB-INF directory

1.2 InternalResourceViewResolver

1.2.1 Overview

InternalResourceViewResolver is the "internal resource view resolver", which is the most commonly used view resolver type in daily development. It is a subclass of URLBasedViewResolver and has all the features of URLBasedViewResolver.

1.2.2 Principle

UrlBasedViewResolver specifies the prefix through the prefix attribute, and the suffix attribute specifies the suffix. When the ModelAndView object returns a specific View name, it will concatenate the prefix prefix and suffix suffix with the specific view name to obtain a specific loading path of the view resource file, thereby loading the real view file and feeding it back to the user.

1.2.3 Configuration

Use UrlBasedViewResolver In addition to configuring the prefix and suffix attributes, you also need to configure "viewClass" to indicate which view to resolve. The sample code is as follows

<!--配置视图解析器之InternalResourceViewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--可以省略-->
    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>    <!--注意路径-->
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>
1.2.3.1 Description
  • InternalResourceViewResolver can automatically resolve the returned view name into an object of type InternalResourceView.
  • InternalResourceView will store the model attributes returned by the Controller processor method into the corresponding request attributes, and then redirect the request forword to the target URL on the server side through the RequestDispatcher. That is to say, when using the InternalResourceViewResolver to resolve the view, there is no need to specify the viewClass attribute separately.

3. Spring MVC execution process

1. Execution flowchart

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-UPAiYIZX-1682512822611) (G:\Desktop\Lesson Preparation\Class\ssm\Courseware Map\Spring MVC Execution Flowchart .png)]

2. Overview of the execution process

The execution flow of SpringMVC is as follows

  1. The user clicks on a request path to initiate an HTTP request request, which will be submitted to DispatcherServlet (front controller);
  2. DispatcherServlet requests one or more HandlerMapping (processor mapper), and returns an execution chain (HandlerExecutionChain).
  3. DispatcherServlet sends the Handler information returned by the execution chain to HandlerAdapter (processor adapter);
  4. HandlerAdapter finds and executes the corresponding Handler (often called Controller) according to the Handler information;
  5. After the Handler is executed, it will return a ModelAndView object to the HandlerAdapter (the underlying object of Spring MVC, including the Model data model and View view information);
  6. After the HandlerAdapter receives the ModelAndView object, it returns it to the DispatcherServlet;
  7. After DispatcherServlet receives the ModelAndView object, it will request ViewResolver (view resolver) to resolve the view;
  8. ViewResolver matches the corresponding view result according to View information, and returns it to DispatcherServlet;
  9. After receiving the specific View view, DispatcherServlet renders the view, fills the model data in the Model into the request field in the View view, and generates the final View (view);
  10. Views are responsible for displaying results to the browser (client).

3. Spring MVC interface

The components involved in Spring MVC are DispatcherServlet (front controller), HandlerMapping (processor mapper), HandlerAdapter (processor adapter), Handler (processor), ViewResolver (view resolver) and View (view). The function description of each component is as follows

3.1 DispatcherServlet

​ DispatcherServlet is the front controller. As can be seen from Figure 1, all requests of Spring MVC must be uniformly distributed through DispatcherServlet.

​ DispatcherServlet is equivalent to a forwarder or central processing unit, which controls the execution of the entire process and uniformly schedules each component to reduce the coupling between components and facilitate the expansion between components.

3.2 Handler Mapping

​ HandlerMapping is a processor mapper, its function is to find a matching handler (Handler) through annotation or XML configuration according to the URL path of the request.

3.3 HandlerAdapter

​ HandlerAdapter is a processor adapter, whose function is to execute the relevant processor (Handler) according to specific rules according to the processor (Handler) found by the mapper.

​ In the servlet stage, in order to solve a request corresponding to a servlet, there are two methods

1. When the method passes parameters, pass one more, and find the corresponding servlet method

2. Encapsulate a baseServlet, which is used to inherit the httpsservlet, and invoke it during operation through reflection. The servlets defined later will inherit the baseServlet

3.4 Handler

​ Handler is a processor, often called Controller, which is consistent with the role played by Java Servlet. Its function is to execute related request processing logic, return corresponding data and view information, and encapsulate it into ModelAndView object.

3.5 View Resolver

​ View Resolver is a view resolver, its role is to perform parsing operations, and resolve the logical view name into a real view View through the View information in the ModelAndView object (such as returning a real JSP page through a JSP path).

3.6 View

​ View is a view, which itself is an interface, and the implementation class supports different View types (JSP, FreeMarker, Thymeleaf, etc.).

四、@Controller、@RequestMapping

​ Spring version 2.5 adds the Spring MVC annotation function to replace the traditional XML-based Spring MVC configuration.

1. Advantages of using annotations

  • Multiple processing methods can be written in the annotation-based controller class, and multiple requests (actions) can be processed, which allows related operations to be written in the same controller class, thereby reducing the number of controller classes and facilitating To be maintained later.
  • Annotation-based controllers do not need to deploy mappings in configuration files, but only need to use @RequestMapping to annotate a method for request processing.

2、@Controller

The @Controller annotation is used to declare that an instance of a class is a controller.

2.1 Steps to use

  1. Add annotations to the Controller class
package com.hqyj.cl.controller;

import org.springframework.stereotype.Controller;

@Controller
public class AnnotationTest {
    
    
    // 方法代码
}
  1. springmvc-servlet.xml configuration package scanning

Spring MVC uses the scanning mechanism to find all annotation-based controller classes in the application. Therefore, in order for the controller class to be scanned by the Spring MVC framework, you need to declare spring-context in the configuration file and use the element to specify the basic package of the controller <context:component-scan/>class (Make sure all controller classes are under the base package and its subpackages).

<!-- 使用扫描机制扫描控制器类,控制器类都在com.hqyj.controller包及其子包下 -->
<context:component-scan base-package="com.hqyj.controller" />

3、@RequestMapping

  • There are multiple methods for processing requests in a controller, such as adding users, modifying user information, deleting specified users, and obtaining user lists according to conditions, etc. in UserController. Each method is responsible for different request operations, and @RequestMapping is responsible for mapping the request to the corresponding controller method.
  • The @RequestMapping annotation can be used on classes or methods. Used on a class, it means that all methods in the class that respond to requests use this address as the parent path.

3.1 Common attributes

3.1.1 value attribute

​ The value attribute is the default attribute of the @RequestMapping annotation, so if there is only the value attribute, the attribute name can be omitted, and if there are other attributes, the value attribute name must be written.

3.1.1.1 Sample code
@RequestMapping(value="user")
@RequestMapping("user")

3.1.2 path property

​ Same usage as the value attribute

3.1.3 name attribute

​ The name attribute is equivalent to the comment of the method, making the method easier to understand.

3.1.3.1 Example code
@RequestMapping(value = "user",name = "用户操作")

3.1.4 method attribute

The method attribute is used to indicate which HTTP requests are supported by the method. If the method attribute is omitted, the method supports all HTTP requests.

3.1.4.1 Sample code
// 只支持 GET 请求
@RequestMapping(value = "selectAllUser",method = RequestMethod.GET)
// 指定支持多个 HTTP 请求,该方法同时支持 GET 和 POST 请求。
@RequestMapping(value = "checkUser",method = {
    
    RequestMethod.GET,RequestMethod.POST})

3.1.5 params property

The params attribute is used to specify the parameters specified in the request.

3.1.5.1 Sample code
// 请求中必须包含 type 参数时才能执行该请求
@RequestMapping(value = "selectAllUser",params = "type")
public String toUser() {
    
    
    return "userList";
}
// 请求中必须包含 type 参数,且 type 参数值为 1 时才能够执行该请求
@RequestMapping(value = "selectAllUser",params = "type=1")
public String toUser() {
    
    
    return "userList";
}

3.2 Mapping by Request URL

3.2.1 Method level annotations

@Controller
public class UserController {
    
    
    @RequestMapping(value = "/user/login")
    public String login() {
    
    
        return "login";
    }
    @RequestMapping(value = "/user/register")
    public String register() {
    
    
        return "register";
    }
}

3.2.2 Class-level annotations

@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @RequestMapping("/login")
    public String login() {
    
    
        return "login";
    }
    @RequestMapping("/register")
    public String register() {
    
    
        return "register";
    }
}

3.3 Mapping by request parameters or methods

​ The value of @RequestMapping indicates the URL of the request; method indicates the request method, which is set as a GET request here. If it is a POST request, it cannot enter the processing method of selectUserByUsername. params indicates the request parameters, where the parameter name is username.

@Controller
public class UserController {
    
    
    @RequestMapping(value = "/user/userList" method=RequestMethod.GET, params="username")
    public String selectUserByUsername(String username) {
    
    
        return "userList";
        
    @RequestMapping(value = "/user/userList2" method=RequestMethod.GET)
    public String selectUserByUsername2(@RequestParam("username") String username) {
    
    
        return "userList";
}

3.4 Parameter types

​ The org.springframework.ui.Model type, which is a Spring MVC type that contains a Map. Spring MVC will create org.springframework.ui.Model objects each time a request handling method is called.

3.4.1 Model type

@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @RequestMapping("/register")
    public String register(Model model) {
    
    
        /*在视图中可以使用EL表达式${success}取出model中的值*/
        model.addAttribute("success", "注册成功");
        return "register";
    }
}

3.4.1 Case

  1. controller
@Controller
@RequestMapping(value = "user",name = "用户操作")
public class UserController {
    
    
    // 登录
    @RequestMapping("/login")
    public String login(Model model){
    
    
        /*在视图中可以使用EL表达式${info}取出model中的值*/
        model.addAttribute("info", "登录成功");
        return "index";
    }
}
  1. index page
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${info},系统首页!
</body>
</html>

Five, Spring MVC passing parameters

​ There are many ways for Spring MVC Controller to receive request parameters, some are suitable for get request methods, some are suitable for post request methods, and some are suitable for both. There are mainly the following ways:

  • Receive request parameters through entity bean
  • Receive request parameters through the formal parameters of the processing method
  • Receive request parameters through HttpServletRequest
  • Receive request parameters in the URL through @PathVariable
  • Receive request parameters through @RequestParam

1. Receive request parameters through entity bean

Entity Bean receiving request parameters is applicable to get and post submitting request methods. It should be noted that the property name of the Bean must be the same as the name of the request parameter. The sample code is as follows

@RequestMapping("/login")
public String login(User user, Model model) {
    
    
    if ("admin".equals(user.getUsername())
            && "112112".equals(user.getPassword())) {
    
    
        model.addAttribute("message", "登录成功");
        return "index"; // 登录成功,跳转到 index.jsp
    } else {
    
    
        model.addAttribute("message", "用户名或密码错误");
        return "login";
    }
}

url get request background method splicing parameters

2. Receive request parameters through the formal parameters of the processing method

​ To receive request parameters through the formal parameters of the processing method is to directly write the form parameters in the formal parameters of the corresponding method of the controller class, that is, the formal parameter names are exactly the same as the request parameter names. This method of receiving parameters is applicable to get and post submission requests. The sample code is as follows

@RequestMapping("/login")
public String login(String username, String password, Model model) {
    
    
    if ("admin".equals(username)
            && "112112".equals(password)) {
    
    
        model.addAttribute("message", "登录成功");
        return "index"; // 登录成功,跳转到 index.jsp
    } else {
    
    
        model.addAttribute("message", "用户名或密码错误");
        return "login";
    }
}

3. Receive request parameters through HttpServletRequest

​ Same as the acquisition method in the servlet phase, the controller layer method parameters include the HttpServletRequest parameter, and the parameters in the request can be obtained.

4. Receive the request parameters in the URL through @PathVariable

@RequestMapping(value = "/login/{username}/{password}")
public String login(@PathVariable("username") String username, @PathVariable("password") String password) {
    
    
    System.out.println(username);
    System.out.println(password);
    return "index";
}

​ When accessing http://localhost:8080/user/login/admin/123456the path, the above code will automatically bind the template variables {username} and {password} in the URL to the parameters of the same name annotated by @PathVariable, namely username=admin, password=123456.

5. Receive request parameters through @RequestParam

Use the @RequestParam annotation at the method parameter to specify its corresponding request parameters. @RequestParam has the following three parameters:

  • value: parameter name;
  • required: Whether to include this parameter, the default is true, indicating that the request path must include this parameter, if not included, an error will be reported;
  • defaultValue: the default parameter value, if this value is set, required=true will be invalid, and it will be false automatically, if this parameter is not passed, the default value will be used

Receiving request parameters through @RequestParam is applicable to get and post submission request methods, the sample code is as follows

  1. UserController
@RequestMapping("/goRequestParam")
private String goRequestParam(){
    
    
    return "requestParam";
}
@RequestMapping("/requestParam")
public String requestParam(
    @RequestParam(value = "username",required = true) String username, 
    @RequestParam(value = "password",required = false,defaultValue = "111") String password){
    
    
    System.out.println(username + " " + password);
    return "index";
}
  1. requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>RequestParam</title>
</head>
<body>
<form action="/user/requestParam" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="submit">
</form>
</body>
</html>
  1. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
<a href="../user/login">登录</a><br>
<a href="../user/register">注册</a><br>
<a href="../user/goRequestParam">RequestParam</a><br>
</body>
</html>

​ The difference between this method and "Receive request parameters through the formal parameters of the processing method" is as follows: When the request parameters are inconsistent with the received parameter names, "Receive request parameters through the formal parameters of the processing method" will not report a 400 error, while "By @ RequestParam "receive request parameters" will report a 400 error.

Six, Spring MVC redirection and forwarding

  • Spring MVC request methods are divided into two types: forwarding and redirection, which are processed at the controller layer using forward and redirect keywords respectively.
  • In the Spring MVC framework, the return statement of the processing method in the controller class is forwarded by default , but it is forwarded to the view.
  • Redirection is to direct the user from the current processing request to another view (such as JSP) or processing request. All the information stored in the previous request (request) will be invalidated and enter a new request scope;
  • Forwarding is to forward the user's current processing request to another view or processing request, and the information stored in the previous request will not be invalidated.
  • Forwarding is a server behavior, redirection is a client behavior.

1. Forwarding process

  • The client browser sends an http request, and the web server accepts the request, calls an internal method to complete the request processing and forwarding actions inside the container, and sends the target resource to the client; the forwarding path here must be the URL under the same web container, It cannot be redirected to other web paths, and the request in its own container is passed in the middle.
  • What is displayed in the address bar of the client's browser is still the path of its first visit, that is to say, the client does not feel that the server has made a forwarding. The forwarding behavior is that the browser only makes one access request.

2. Redirection process

  • The client browser sends an http request, and the web server sends a 302 status code response and the corresponding new location to the client browser after accepting it. When the client browser finds that it is a 302 response, it automatically sends a new http request, and the request URL is the new location Address, the server finds the resource based on this request and sends it to the client.
  • The location here can be redirected to any URL. Since the browser reissues the request, there is no concept of request delivery. The redirection path is displayed in the address bar of the client's browser, and the client can observe the change of the address. The redirection behavior is that the browser makes at least two access requests.

3. Case

@RequestMapping("/login")
public String login() {
    
    
    //转发到一个请求方法(同一个控制器类可以省略/index/)
    return "forward:/user/isLogin";
}
@RequestMapping("/isLogin")
public String isLogin() {
    
    
    //重定向到一个请求方法
    return "redirect:/user/isRegister";
}
@RequestMapping("/isRegister")
public String isRegister() {
    
    
    //转发到一个视图
    return "register";
}

4. Matters needing attention

​ In the Spring MVC framework, whether it is redirection or forwarding, it needs to conform to the configuration of the view resolver. If it is directly forwarded to a resource that does not require DispatcherServlet, for example

return "forward:/html/my.html";

You need to configure in springmvc-servlet.xml

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

7. @Autowired and @Service

The @Autowired and @Service annotations are required to inject dependencies into Spring MVC controllers.

1 Introduction

​ The @Autowired annotation belongs to the org.springframework.beans.factory.annotation package, which can annotate class member variables, methods and constructors to complete the work of automatic assembly;

​ The @Service annotation belongs to the org.springframework.stereotype package, and will automatically register the annotation class into the Spring container.

2. Case

  1. springmvc-servlet.xml

Elements need to be added in the configuration file springmvc-servlet.xml <component-scan/>to scan dependent basic packages

<context:component-scan base-package="com.hqyj.cl.service"/>
  1. Entity class
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private String name;
    private String pwd;
}
  1. Create the UserService interface
public interface UserService {
    
    
    boolean login(User user);
    boolean register(User user);
}
  1. Create a UserServiceImpl class to implement the UserService interface
@Service
public class UserServiceImpl implements UserService {
    
    
    @Override
    public boolean login(User user) {
    
    
        if ("admin".equals(user.getName()) && "111".equals(user.getPwd())) {
    
    
            return true;
        }
        return false;
    }
    @Override
    public boolean register(User user) {
    
    
        if ("admin".equals(user.getName()) && "111".equals(user.getPwd())) {
    
    
            return true;
        }
        return false;
    }
}

Note: The function of adding @Service annotation is to enable the class to be scanned by Spring

  1. Create the UserController class
@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @Autowired
    private UserService userService;
    @RequestMapping("/login")
    public String getLogin(Model model) {
    
    
        User user = new User();
        user.setName("admin");
        user.setPwd("111");
        userService.login(user);
        model.addAttribute("user", user);
        return "login";
    }
    @RequestMapping("/register")
    public String getRegister(Model model) {
    
    
        User user = new User();
        user.setName("admin");
        user.setPwd("111");
        userService.login(user);
        model.addAttribute("user", user);
        return "register";
    }
}

Note: Adding the @Autowired annotation on UserService will cause an instance of UserService to be injected into the UserController instance

  1. springmvc-servlet.xml
<!-- 配置包扫描路径,作用自动检测标注Bean -->
<context:component-scan base-package="com.hqyj.cl" />
<mvc:annotation-driven />
<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceView">
    <!--前缀 -->
    <property name="prefix" value="/WEB-INF/jsp/" />
    <!--后缀 -->
    <property name="suffix" value=".jsp" />
</bean>
  1. web.xml
<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

  1. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
<h2>Hello World!</h2>
未注册的用户,请
<a href="${pageContext.request.contextPath}/user/register"> 注册</a>!
<br /> 已注册的用户,去
<a href="${pageContext.request.contextPath}/user/login"> 登录</a>!
</body>
</html>
  1. login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
    登录页面! 欢迎 ${user.name} 登录
</body>
</html>
  1. register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
    注册页面!
    注册账号成功,用户名为: ${user.name }
</body>
</html>

Eight, @ModelAttribute (understand)

​ The very important annotation @ModelAttribute in Spring MVC is used to bind request parameters to Model objects. The model object is created before the controller method, so the method annotated by @ModelAttribute will be executed before each method of the Controller is executed. use as little as possible

1. Purpose

  • applied to the method
  • applied to method parameters
  • Applied to the method, and the method also uses @RequestMapping

1.1 Applied to the method

1.1.1 Applied to methods with no return value

  1. ModelAttributeController
@Controller
@RequestMapping("/model")
public class ModelAttributeController {
    
    
    // 方法无返回值
    @ModelAttribute
    public void myModel(@RequestParam(required = false) String name, Model model) {
    
    
        model.addAttribute("name", name);
    }
    @RequestMapping("/index")
    public String model() {
    
    
        return "index";
    }
    
    // 上述代码合二为一
    /*    @RequestMapping("/index")
    public String model(@RequestParam(required = false) String name, Model model) {
        model.addAttribute("name", name);
        return "index";
    }*/
}
  1. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${name}
</body>
</html>

access:

​ Using http://localhost:8080/model/index?name=%E5%BC%A0%E4%B8%89access, the page will display the value corresponding to the name. Tip: The string after the name is not garbled characters, but a string conversion problem. The meaning here is Zhang San.

1.1.2 Applied to methods with return values

​ Using this method, the return value object name will be placed in the implicit Model by default. In the Model, the key is the lowercase initial letter of the return value type, and the value is the returned value. Equivalent tomodel.addAttribute("string", name);

  1. ModelAttributeController
@Controller
@RequestMapping("/model")
public class ModelAttributeController {
    
    
     // 方法有返回值
    @ModelAttribute()
    public String myModel(@RequestParam(required = false) String name) {
    
    
        return name;
    }
    @RequestMapping("/index")
    public String model() {
    
    
        return "index";
    }
}
  1. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${string}
</body>
</html>

​ Under normal circumstances, try not to return values ​​of data types such as string, int, and float in the program. Use @ModelAttribute to annotate the value attribute to customize the key, sample code

@ModelAttribute("name")
public String myModel(@RequestParam(required = false) String name) {
    
    
    return name;
}

Equivalent to

model.addAttribute("name", name);

1.2 Applied to the parameters of the method

​ @ModelAttribute is annotated on the parameters of the method. When the method is called, the value of the model will be injected. This is very simple in practice and is often used to map form attributes to ** model objects. **

  1. ModelAttributeController
@Controller
@RequestMapping("/model")
public class ModelAttributeController {
    
    
    @RequestMapping("/register")
    public String register(@ModelAttribute("user") User user) {
    
    
        if ("admin".equals(user.getName()) && "111".equals(user.getPwd())) {
    
    
            return "login";
        } else {
    
    
            return "register";
        }
    }
}
  1. login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
登录页面! 欢迎 ${user.name} 登录
</body>
</html>
  1. index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
注册页面!
注册账号成功,用户名为: ${user.name }
</body>
</html>

1.2.1 Description

@ModelAttribute("user") User The user statement has two functions:

  • Encapsulate the input of request parameters into the user object
  • Create a User instance

​ It is stored in the Model object with "user" as the key value, which has the same function as the "model.addAttribute("user",user)" statement. If no key value is specified, that is, "@ModelAttribute User user", then when creating a User instance, "user" is stored as the key value in the Model object, which has the same function as the "model.addAtttribute("user", user)" statement .

1.3 ModelAttribute+RequestMapping

  1. ModelAttributeController
@Controller
public class ModelAttributeController {
    
    
    // @ModelAttribute和@RequestMapping同时放在方法上 方法直接返回页面名称 会把类路径拼接到url中
    @RequestMapping("/index")
    @ModelAttribute("name")
    public String model(@RequestParam(required = false) String name) {
    
    
        return name;
    }
}
  1. index.jsp

    The request path is http://localhost:8080/j230101SpringMVC_war_exploded/index?name=admin The name parameter has a value

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${name}
</body>
</html

1.3.1 Description

When @ModelAttribute and @RequestMapping annotations are applied to methods at the same time, they have the following effects:

  1. The return value of the method will be stored in the Model object, and the key is the value attribute value of the ModelAttribute;
  2. The return value of the method is no longer the access path of the method, and the access path will become the value value of @RequestMapping, for example: @RequestMapping(value = “/index”) The redirected page is the index.jsp page;
  3. When using this method, do not add a class path, otherwise it may cause path errors.

1.4 The difference between Model and ModelAndView

  • Model: The default parameter that exists in each request, and its addAttribute() method can be used to pass the value of the server to the client page.
  • ModelAndView: Contains two parts, model and view. When using it, you need to instantiate it yourself, use Model to pass values, and you can also set the name of view.

1.5 Exercises

The method annotated with @ModelAttribute will be called before each request processing method of the controller class. This feature can be used to control login permissions.

  1. BaseController
public class BaseController {
    
    
    @ModelAttribute
    public void isLogin(HttpSession session) throws Exception {
    
    
        if (session.getAttribute("user") == null) {
    
    
            throw new Exception("没有权限");
        }
    }
}
  1. UserController
@RequestMapping("/user")
public class UserController extends BaseController {
    
    
    @RequestMapping("/selectAllUser")
    public String selectAllUser() {
    
    
        return "userList";
    }
}

Nine, Spring MVC JSON data interaction

​ Spring MVC needs to convert the format and type of the transmitted data in the process of data binding. It can convert data of types such as String and other types of data such as JSON. We use Alibaba's FastJson technology to implement Spring MVC to process data in JSON format. The page needs to introduce jquery. Pay attention to resource filtering (the first way). Spring version 4.0.2 (4.3.13 other package versions are too low, but 4.0 does not support the name attribute of requestmaping)

1. Case

  1. Import dependencies in the pom.xml file (imported before)
<!-- 格式化对象,方便输出日志 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.1.41</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<!-- jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.6</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.6</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.6</version>
</dependency>
  1. The return value of the JSONController method can be set as a Map collection
@Controller
@RequestMapping("/json")
public class JSONController {
    
    
    @RequestMapping("/index")
    public String index() {
    
    
        return "index";
    }
    @RequestMapping("/testJson")
    @ResponseBody
    public User testJson(User user) {
    
    
        // 打印接收的 JSON数据
        System.out.println("username=" + user.getUsername() + ",password=" + user.getPassword());
        // 返回JSON格式的响应
        return user;
    }
}
  1. index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>测试JSON交互</title>
    <script type="text/javaScript" src="../static/js/jquery-2.1.1.min.js"></script>
</head>
<body>
<form>
    用户名:<input type="text" name="username" id="username"/>
    <br>
    密码:<input type="password" name="password" id="password"/>
    <br>
    <input type="button" value="login" οnclick="login()"/>
</form>
</body>
<script type="text/javaScript">
    function login() {
        $.ajax({
            //请求路径
            url: "../json/testJson",
            //请求类型
            type: "post",
            //定义回调响应的数据格式为JSON字符串,该属性可以省略
            dataType: "json",
            //data表示发送的数据
            data: {
                username: $("#username").val(),
                password: $("#password").val(),
            },
            contentType: "application/x-www-form-urlencoded", //设置请求参数的格式
            processData: true, //设置ajax内部是否自动处理请求参数,默认为true,可省略,如果data给的是个js对象,要么不设置,要么设为true
            //成功响应的结果
            success: function (data) {
                if (data != null) {
                    alert("输入的用户名:" + data.username + ",密码:" + data.password);
                }
            },error:function () {
                alert("服务器错误");
            }
        });
    }
</script>
</html>

2、contentType

There are three common types of contentType:

// 普通表单提交的数据的格式为application/x-www-form-urlencoded
application/x-www-form-urlencoded
// 发送以ContentType为application/json格式的请求参数,需要把data的内容转为json格式,使用JSON.stringify(param)
application/json
// 上传文件时,请求消息将以multipart/form-data格式封装请求参数
multipart/form-data

// To send request parameters with ContentType as application/json format, you need to convert the content of data to json format, use JSON.stringify(param)
application/json

Variables can be defined in ajax

let user = JSON.stringify({

​ username:$(“username”).val(),

​ password:$(“password”).val(),

});

The following data: can be modified to:

data:user; To pass to the backend, you need to use the @requestBody annotation in the backend method parameters to get public void login(@requestBodyUser user)

10. Spring MVC Interceptor (Interceptor)

​ The Interceptor of Spring MVC is similar to the filter of Java Servlet. It is mainly used to intercept user requests and do corresponding processing. It is usually used in authority verification, logging of request information, and judging whether users are logged in. And other functions.

1. Define the interceptor

​ Define an interceptor, we implement it by implementing the HandlerInterceptor interface

1.1 Case

  1. Implement the HandlerInterceptor interface
public class MyInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    
    
        // 获取请求的URL
        String url = request.getRequestURI();
        // login.jsp或登录请求放行,不拦截
        if (url.indexOf("/goLogin") >= 0 || url.indexOf("/login") >= 0) {
    
    
            return true;
        }
        // 获取 session
        HttpSession session = request.getSession();
        Object obj = session.getAttribute("user");
        if (obj != null)
            return true;
        // 没有登录且不是登录页面,转发到登录页面,并给出提示错误信息
        request.setAttribute("msg", "还没登录,请先登录!");
        request.getRequestDispatcher("login").forward(request, response);
        return false;
    }
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
    
    
    }
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
    
    
    }
}

The definition of the interceptor implements the HandlerInterceptor interface, and implements the three methods in the interface, explained as follows

  • preHandle( ): This method is executed before the processing request method of the controller. Its return value indicates whether to interrupt the subsequent operation. Returning true indicates that the execution continues downward, and returning false indicates that the subsequent operation is interrupted.
  • postHandle( ): This method is executed after the controller's processing request method is called and before parsing the view. This method can be used to further modify the model and view in the request domain.
  • afterCompletion( ): This method is executed after the processing request method of the controller is executed, that is, it is executed after the view rendering is completed. Through this method, some tasks such as resource cleaning and log information recording can be realized.
  1. springmvc-servlet.xml configuration interceptor
<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/**" />
        <bean class="com.hqyj.cl.utils.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>
  1. UserController
@Controller
@RequestMapping("/user")
public class UserController {
    
    
    // 登录页面初始化
    @RequestMapping("/goLogin")
    public String initLogin() {
    
    
        return "login";
    }

    // 处理登录功能
    @RequestMapping("/login")
    public String login(User user, HttpSession session) {
    
    
        if ("admin".equals(user.getUsername()) && "111".equals(user.getPassword())) {
    
    
            // 登录成功,将用户信息保存到session对象中
            session.setAttribute("user", user);
            // 重定向到主页面的跳转方法
            return "redirect:main";
        }
        return "login";
    }

    // 跳转到主页面
    @RequestMapping("/main")
    public String goMain() {
    
    
        return "main";
    }
    
    // 退出登录
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
    
    
        // 清除 session
        session.invalidate();
        return "login";
    }
}
  1. login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
${ msg }
<form action="../user/login" method="post">
    用户名:<input type="text" name="username" /><br>
    密码:<input type="password" name="password" /><br>
    <input type="submit" value="登录" />
</form>
</body>
</html>
  1. main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
欢迎 ${ sessionScope.get("user").username },登录!<br />
<a href="../user/logout">退出</a>
</body>
</html>

11. File upload and download

1. File upload

  1. Add the following dependencies to the pom.xml file
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2.2</version>
</dependency>
  1. springmvc-servlet.xml
<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="5000000" />
    <property name="defaultEncoding" value="UTF-8" />
</bean>
  • defaultEncoding: The encoding format of the request, the default is ISO-8859-1, here is set to UTF-8 (Note: defaultEncoding must be consistent with pageEncoding in JSP, so as to read the content of the form correctly).
  • maxUploadSize: The upper limit of the uploaded file size, in bytes.
  1. fileUpload.jsp form submission
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
</head>
<body>
    <form action="${pageContext.request.contextPath }/file/upload"
        method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="file"><br> 
        <input type="submit" value="提交">	
    </form>
</body>
</html>
  1. FileController
@Controller
@RequestMapping("/file")
public class FileController {
    
    
    @RequestMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
    
    
        // 获取上传文件名
        String originalFileName = file.getOriginalFilename();
        // 得到当前的classpath的绝对路径的URI表示法
        String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        int index = rootPath.indexOf("target");
        String path = rootPath.substring(1,index) + "src/main/webapp/static/images/book";
        // 新文件
        File newFile = new File(path,originalFileName);
        // 判断目标文件所在目录是否存在
        if( !newFile.getParentFile().exists()) {
    
    
            // 如果目标文件所在的目录不存在,则创建父目录
            newFile.getParentFile().mkdirs();
        }
        // 将内存中的数据写入磁盘
        file.transferTo(newFile);
        return  "success";
    }
}

1.1 Extension

File upload using ajax

    <form id="uploadForm">
        <input type="file" name="file">
        <br>
        <input type="button" value="button" οnclick="upload()">
    </form>
    <script>
        function upload() {
            var formData = new FormData($("#uploadForm")[0]);
            // 发送ajax请求
            $.ajax({
                url:'/file/upload',
                type:"post",
                data:formData,
                processData : false,  //必须false才会避开jQuery对 formdata 的默认处理
                contentType : false,  //必须false才会自动加上正确的Content-Type
                success:function (data) {
                    console.log(data);
                },error:function () {
                    alert("服务器错误");
                }
            })
        }
    </script>

2. File download

  1. fileDown.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件下载</title>
</head>
<body>
<form action="/file/down" method="get">
    <input type="submit" value="下载">
</form>
</body>
</html>
  1. FileController
@RequestMapping("/down")
@ResponseBody
public String down(HttpServletResponse response) throws Exception{
    
    
    // 下载文件的路径
    String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	// 截取到需要的文件存放路径
    int index = rootPath.indexOf("target");
    String path = rootPath.substring(1,index) + "src/main/webapp/static/images/book";
    // 下载文件的名字,假设为banner_1.jpg
    String fileName = "banner_1.jpg";
    //获取输入流
    InputStream is = new BufferedInputStream(new FileInputStream(new File(path,fileName)));
    //转码,免得文件名中文乱码
    String filename = URLEncoder.encode(fileName,"UTF-8");
    //设置文件下载头
    response.addHeader("Content-Disposition", "attachment;filename=" + filename);
    //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
    response.setContentType("multipart/form-data");
    BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
    int len = 0;
    while((len = is.read()) != -1){
    
    
        out.write(len);
        out.flush();
    }
    out.close();
    return "success";
}

12. SpringMVC resource filtering problem

**Problem description:** In the web.xml file, after configuring the following code, all request URLs will be intercepted, including js, css and other static resources, which makes us unable to use these static resources.

<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

** One of the solutions: **In the springmvc-servlet.xml file, add the following code

<!-- 默认的注解映射,必须加,不然没办法兼顾二者 -->
<mvc:annotation-driven />
<!--配置静态资源放行 如果web.xml中servlet-name定义为default,则default-servlet-name="default"可以不写-->
<mvc:default-servlet-handler default-servlet-name="default"/>

In the web.xml file, add the following code

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

**Solution 2: **In the springmvc-servlet.xml file, add the following code

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 包扫描-->
    <context:component-scan base-package="com.hqyj.cl.controller"/>
    <!-- 默认的注解映射,必须加,不然没办法兼顾二者 -->
    <mvc:annotation-driven />
    <mvc:resources mapping="/static/**" location="/static/"/>
	<!-- interceptors -->  
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!-- 不拦截的请求 -->
            <mvc:exclude-mapping path="/static/**"/>
            <bean class="com.hqyj.cl.utils.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--配置视图解析器之InternalResourceViewResolver-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--指定viewclass 必须指定-->
        <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
        <!--前缀-->
        <property name="prefix" value="/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  • location: means that the directory specified by location should not be intercepted and requested directly, here refers to all files under the resources file in the root directory
  • mapping: Refers to all files under the resources file (** represents all files)

Guess you like

Origin blog.csdn.net/ailaohuyou211/article/details/130394223