概述
本教程将重点介绍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
路由到TestController
的getTestData
方法。
当然,我们还返回了一些模型数据的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上找到。