概述

本教程将重点介绍Spring MVC中的核心概念:控制器。

1. 引言

首先,让我们退一步,了解一下典型Spring MVC架构中的Front Controller概念。

从高层次来看,控制器的主要职责包括:

  • 处理传入请求
  • 将请求负载转换为内部数据结构
  • 将数据传递给Model进行进一步处理
  • Model获取处理后的数据,并将其传递给View进行渲染

以下是Spring MVC中高层次流程的快速图示:

如图所示,DispatcherServlet在架构中扮演Front Controller的角色。

这个图适用于传统的MVC控制器以及RESTful控制器,只是有一些小差异(下面会描述)。

在传统方法中,MVC应用不是服务导向的,因此有一个View Resolver,它根据来自控制器的数据渲染最终视图。

RESTful应用设计为服务导向,返回原始数据(通常为JSON或XML)。由于这些应用不进行视图渲染,没有View Resolvers,控制器通常期望直接通过HTTP响应发送数据。

我们先从MVC风格的控制器开始。

2. Maven依赖

要在Spring Boot中使用Spring MVC,我们首先需要处理Maven依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.0.2</version>
</dependency>

要获取库的最新版本,请查看Maven中央仓库的spring-boot-starter-web

3. Spring Boot Web配置

现在来看看如何配置Spring Boot。由于我们在类路径中添加了thymeleaf依赖,所以不需要为它配置任何@Bean

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

在我们的WebConfig中,我们需要为Geeting对象和ObjectMapper添加一个bean,以启用默认的servlet:

    @Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> enableDefaultServlet() {
        return factory -> factory.setRegisterDefaultServlet(true);
    }

    @Bean
    public Greeting greeting() {
        Greeting greeting = new Greeting();
        greeting.setMessage("Hello World !!");
        return greeting;
    }

    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }

例如,如果控制器返回名为welcome的视图,view resolver会尝试在templates文件夹中查找名为welcome.html的页面。这是Thymeleaf搜索视图的默认文件夹。

4. MVC控制器

现在我们将实现MVC风格的控制器。

注意,我们正在返回一个包含模型映射和视图对象的ModelAndView对象,它们都将由View Resolver用于数据渲染:

@Controller
@RequestMapping(value = "/test")
public class TestController {

    @GetMapping
    public ModelAndView getTestData() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("welcome");
        mv.getModel().put("data", "Welcome home man");

        return mv;
    }
}

那么这里设置了什么?

首先,我们创建了一个名为TestController的控制器,并将其映射到"/test"路径。在类中,我们创建了一个返回ModelAndView对象的方法,它与GET请求关联。因此,任何以“test”结尾的URL调用都将由DispatcherServlet路由到TestControllergetTestData方法。

当然,我们还返回了一些模型数据的ModelAndView对象。

视图对象的名称设置为"welcome"。如上所述,View Resolver会在templates文件夹中搜索名为welcome.html的页面。

下面是GET操作的一个示例结果:

欢迎

5. REST控制器

REST应用程序的设置与MVC应用程序相同,唯一的区别是不存在View Resolvers或模型映射。

API通常将原始数据返回给客户端,通常是XML和JSON表示形式,因此DispatcherServlet会跳过view resolvers,并将数据直接返回到HTTP响应体中。

让我们看看一个简单的RESTful控制器实现:

@RestController
public class RestController {

    @GetMapping(value = "/student/{studentId}")
    public Student getTestData(@PathVariable Integer studentId) {
        Student student = new Student();
        student.setName("Peter");
        student.setId(studentId);

        return student;
    }
}

下面是输出的一个快照:

学生端点

上述输出是通过带有学生ID为1的GET请求发送到API的结果。

这里需要注意的是,@RequestMapping注解是我们真正需要深入探索的一个中心注解,以便充分利用其功能。

6. Spring Boot与@RestController注解

Spring Boot中的@RestController注解基本上是一个快捷方式,可以避免我们总是需要定义@ResponseBody

下面是使用新注解的先前示例控制器:

@RestController
public class RestAnnotatedController {
    @GetMapping(value = "/annotated/student/{studentId}")
    public Student getData(@PathVariable Integer studentId) {
        Student student = new Student();
        student.setName("Peter");
        student.setId(studentId);

        return student;
    }
}

7. 结论

本文介绍了在Spring Boot中使用控制器的基本知识,既包括传统的MVC应用,也包括RESTful API。

如往常一样,文章中的所有代码都可以在GitHub上找到。


» 下一篇: Spring MVC与Velocity