Skip to content

4 Spring MVC

Features to Implement

  • Sign in/Sign up
  • Load restaurant/menus
  • Add item to customer's

Structure of this project

Screenshot 2023-10-23 at 16.48.52

Goal

  • Understand the concept of MVC
  • What is the Spring MVC framework used for
  • How to use the Spring MVC to build REST API

What is MVC?

The Model-View-Controller(MVC) is an architectural pattern that commonly used for presentation tier that divide the related program logic into three interconnected elements.

  • Model: The Model component corresponds to all the data-related logic that the user works with (管理这个模块中的数据)
  • View: The view component is used for all the UI logic of the application (主要用于显示数据和提交请求)
  • Controller: Controllers act as an interface between Model and View components to process all the business logic and incoming requests, manipulate data using the Model component and interact with the Views to render the final output(主要用作捕获并控制请求转发).

Screenshot 2023-10-23 at 16.55.19

  1. Web浏览器发送HTTP请求到服务端, 被Controller(Servlet)获取并进行处理 (例如参数解析, 请求转发)
  2. Controller(Servlet) 调用核心业务逻辑--Model部分, 获得结果
  3. Controller(Servlet) 将逻辑处理结果交给View(JSP), 动态输出HTML内容
  4. 动态生成的HTML内容返回到浏览器显示

What is Spring Web MVC?

The Spring MVC framework provides MVC architecture and components that can be used to develop flexible and loosely coupled web applications. It is designed around a DispatcherServlet that handles all the HTTP requests and responses and discovers the delegate components for actual work.

Screenshot 2023-10-23 at 17.48.14

Screenshot 2023-10-23 at 17.48.29

Annotation used for defining RESTful API

Add below dependency to the pom.xml file

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>6.0.11</version>
        </dependency>

Reload and Install.

@Controller

Use @controller to mark a class its role as a web component, so the spring mvc will register the methods which annotated the @RequestMapping.

Spring框架的Web MVC组件

Spring Web MVC是Spring框架的一部分,专门用于构建基于Web的应用程序。MVC代表模型-视图-控制器,是一种设计模式,用于将应用程序的逻辑、数据和用户界面分离。

  1. 模型 (Model): 表示应用程序的数据和业务逻辑。通常与数据库交互。
  2. 视图 (View): 是用户与应用程序交互的部分,如HTML、JSP页面等。
  3. 控制器 (Controller): 接受用户的请求,处理它,并返回适当的视图。

Spring提供的类、注解和功能

当我们在项目中包含spring-webmvc依赖时,我们可以使用Spring提供的一系列类、注解和功能来更简单地开发Web应用程序:

  1. @Controller 和 @RestController: 这些注解用于标记一个类为Spring MVC控制器。@RestController是一个特殊的@Controller,它假设类中的每个方法都返回一个对象,该对象将自动转换为JSON或XML,并写入HTTP响应。
  2. @RequestMapping: 这个注解用于映射web请求到特定的处理程序方法。它可以根据URL、HTTP方法、请求参数、请求头等来定义这些映射。
  3. @PathVariable, @RequestParam, @RequestBody: 这些注解用于从HTTP请求中提取数据。例如,从URL、查询参数或请求体中。
  4. View Resolvers: Spring MVC使用视图解析器来解析视图。例如,可以使用JSP、Thymeleaf、FreeMarker等作为视图。
  5. Data Binding: Spring MVC允许你直接绑定请求参数到Java对象,这使得数据的处理变得非常简单。
  6. Form Validation: Spring MVC提供了强大的验证机制,你可以使用注解如@Valid来验证表单数据。
  7. Exception Handling: 通过使用@ExceptionHandler@ControllerAdvice,你可以轻松地处理控制器中的异常。

这只是Spring Web MVC提供的功能的一部分,实际上还有更多。它为开发者提供了一整套工具和功能,使得开发Web应用程序变得简单和高效

Create a SignUpController class under controller package.

Screenshot 2023-10-23 at 19.37.56

package com.example.onlineorder.controller;

import org.springframework.stereotype.Controller; 
// 导入了Spring框架中的@Controller注解。这个注解是Spring的一部分,用于标识一个类作为Spring MVC控制器的组件


// 这是@Controller注解的使用。这个注解告诉Spring,SignUpController类是一个控制器,并且应该被Spring的应用上下文管理。当使用此注解时,Spring将自动检测此类并将其注册为Spring容器的一个bean
@Controller
public class SignUpController {
  //这是SignUpController类的定义。目前,这个类是空的,但基于其名称,我们可以猜测它可能会用于处理与用户注册相关的请求
}

//总结:这段代码定义了一个名为SignUpController的控制器类,该类目前是空的,但它已被标记为Spring MVC控制器,这意味着您可能会在其中添加处理HTTP请求的方法

当使用此注解时,Spring将自动检测此类并将其注册为Spring容器的一个bean:

在Spring框架中,核心的概念之一是所谓的"Inversion of Control" (IoC)容器。简单来说,IoC容器负责管理应用程序中对象的生命周期和依赖关系。这些由容器管理的对象被称为"beans"。

当我们在类上使用@Controller(或其他像@Service@Repository@Component等的Spring提供的特定注解)时,我们其实是在告诉Spring的IoC容器:“嘿,这是一个重要的类,我希望你能管理它!”

现在,当Spring应用程序启动时,它会扫描项目中所有的类。当它发现有上述注解标记的类时,它会自动为这个类创建一个实例,并将这个实例注册到IoC容器中。这样,其他的类就可以从容器中注入(或获取)这个类的实例了,而不需要我们手动去创建它。

这种自动检测和注册的行为有以下几点好处:

  1. 自动化管理: 我们不需要手动创建对象和管理它们的生命周期。Spring为我们处理了这些。
  2. 依赖注入: 由于Spring知道所有注册的beans,当某个bean需要另一个bean时(例如,一个服务需要访问数据库,因此它需要一个数据源bean),Spring可以自动为它提供(或“注入”)所需的bean。
  3. 集中化的配置: 我们可以在一个地方(例如,Spring的配置文件或使用注解)配置所有的beans,而不是在整个代码库中散布配置。
  4. 易于测试: 由于依赖是被注入的,所以在测试时,我们可以轻松地为特定的beans提供替代实现或模拟对象。

简而言之,当我们说“Spring将自动检测此类并将其注册为Spring容器的一个bean”时,我们的意思是,Spring会自动识别、实例化这个类,并将其管理在IoC容器中,使其可以在整个应用程序中被其他类引用和使用。

@RequestMapping

Use the @RequestMapping annotation to define REST API, such as HTTP URL, method, etc.

Update SignUpController.java

package com.example.onlineorder.controller;

import com.example.onlineorder.entity.Customer;
// 导入了之前定义的Customer实体类,这个类表示一个客户或用户
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
// 这些是从Spring框架中导入的类和注解,用于创建Web控制器并处理HTTP请求

// 这个注解告诉Spring框架,SignUpController类是一个MVC控制器,它应该被Spring的IoC容器管理
@Controller
public class SignUpController { //定义SignUpController类的开始
    @RequestMapping(value = "/signup", method = RequestMethod.POST)
  //这个@RequestMapping注解告诉Spring框架,当应用程序收到一个指向/signup的POST请求时,应该调用下面的signUp方法
    @ResponseStatus(value= HttpStatus.CREATED)
  //@ResponseStatus注解指定了当signUp方法被成功调用后,应该返回的HTTP状态码。在这里,它是HttpStatus.CREATED,这意味着返回的状态码是201,通常表示一个资源已经成功地被创建
    public void signUp(@RequestBody Customer customer){
      //这是signUp方法的定义。它接受一个参数,这是一个Customer类型的对象。
      //@RequestBody注解告诉Spring,它应该从HTTP请求的主体中读取客户的数据,并自动将其转换为Customer对象
    }

}
// 总的来说,这个SignUpController类定义了一个处理用户注册的简单控制器,当有人向/signup发送一个POST请求并提供了相关的客户数据时,这个方法会被调用。

@RequestBody

Convert the request body in the http request to a backend object. For example,

{
    "firstName": "xxx",
    "lastName": "yyy",
    "email": "test@gmail.com",
    "password": "111"
}

This json payload will be converted to a customer object which includes all information the caller provided.

@RequestMapping(value="/signup", method=RequestMethod.POST)
public void signUp(@RequestBody Customer customer){
  // business logic
}

在Spring框架中,这个注解通常与处理HTTP POST或PUT请求的方法一起使用,用于自动将请求主体的内容(通常为JSON格式)转换为Java对象。在这个示例中,请求主体中的JSON数据会被自动转换为Customer对象。因此,customer对象会包含以下信息:

  • firstName: "xxx"
  • lastName: "yyy"
  • email: "test@gmail.com"
  • password: "111"

之后,您可以在signUp方法内部对这个Customer对象执行任何所需的业务逻辑,例如保存到数据库或进行其他处理。

注意: 为了使这种自动转换工作,您通常需要在您的项目中包含一个适当的JSON库,例如Jackson,它可以与Spring配合工作来执行这种序列化和反序列化操作

https://docs.google.com/document/d/1axaMAhcAlWENBMjmcyEB7McckQwWPWJ9CgaZEh0JAqQ/edit#heading=h.8old7qqhtlxt

Create ApplictionConfig.java

Add onlineOrder-servlet.xml under WEB-INF folder.

Screenshot 2023-10-23 at 20.06.52

Override onlineOrder-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 这是XML声明行,它定义了文档的版本和字符编码 -->
<!-- <beans ...>:
这是配置文件的根元素。所有的Spring配置bean都会在此元素内定义 -->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!-- xmlns 和 xsi:schemaLocation:
这些属性定义了XML文档使用的XML命名空间及其对应的XML模式位置。这些都是为了确保XML文档的内容符合Spring框架的预期格式 -->

       <!-- Path: src/main/webapp/WEB-INF/onlineOrder-servlet.xml -->
       <context:component-scan base-package="com.example.onlineOrder.controller" />
        <!-- <context:component-scan base-package="com.example.onlineOrder.controller" />:
这是一个非常重要的配置元素。它告诉Spring框架在哪个包内搜索带有特定注解的类(如@Controller, @Service, @Repository等),并将这些类注册为Spring容器的bean。在这里,它指定了com.example.onlineOrder.controller作为要扫描的包-->

</beans>

在该配置文件中,基本上您正在告诉Spring:“请去com.example.onlineOrder.controller包中查找所有带有Spring注解的类,并把它们注册为Spring管理的beans”。

这是Spring框架自动装配bean的一个关键部分,它避免了您需要为每一个bean手动写入XML配置

Override web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- 这是XML声明行,定义了文档的版本和字符编码 -->

<!-- <web-app ...>: 这是整个Web应用配置的根元素-->
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">
<!-- xmlns, xmlns:xsi, 和 xsi:schemaLocation: 这些属性定义了XML命名空间和XML模式的位置,以确保web.xml文件内容的结构正确; version="6.0": 指定了该应用程序使用的Jakarta EE版本 -->

    <display-name>OnlineOrder Website</display-name>
  <!-- 定义了Web应用程序的显示名称,这个名称通常在应用服务器的管理控制台中显示 -->
    <servlet>
        <servlet-name>onlineOrder</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
  <!-- 这个元素定义了一个servlet。在这里,定义了一个名为onlineOrder的servlet,它使用org.springframework.web.servlet.DispatcherServlet类,这是Spring MVC的中央servlet,用于处理所有的请求和调度到适当的控制器-->

    <servlet-mapping>
        <servlet-name>onlineOrder</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
  <!-- 这个元素定义了如何将URL模式映射到servlet。在此例中,<url-pattern>/</url-pattern>意味着将所有的请求都映射到onlineOrder servlet,它是Spring MVC的DispatcherServlet-->
</web-app>

这是一个Jakarta EE (曾经是Java EE)的web.xml部署描述文件,用于配置Web应用程序。在这个文件中,主要配置了一个名为onlineOrder的servlet,该servlet是Spring框架的DispatcherServlet,它是Spring MVC的核心组件.

简而言之,这个web.xml文件配置了Web应用程序,使所有进入的请求都由Spring MVC的DispatcherServlet处理,从而将请求转发到适当的控制器进行处理.

Screenshot 2023-10-23 at 20.30.59

Screenshot 2023-10-23 at 20.31.08