构建 RESTful Web 服务

本指南将引导你完成使用 Spring 创建“Hello, World”RESTful Web 服务的过程。

你将构建什么

你将构建一个将在 https://127.0.0.1:8080/greeting 接受 HTTP GET 请求的服务。

它将以问候语的 JSON 表示形式进行响应,如下表所示

{"id":1,"content":"Hello, World!"}

你可以使用查询字符串中的可选 name 参数自定义问候语,如下表所示

https://127.0.0.1:8080/greeting?name=User

name 参数值覆盖 World 的默认值,并反映在响应中,如下表所示

{"id":1,"content":"Hello, User!"}

你需要什么

如何完成本指南

与大多数 Spring 入门指南 一样,你可以从头开始完成每一步,或者你可以绕过你已经熟悉的简单设置步骤。无论哪种方式,你最终都会得到可用的代码。

从头开始,请转到 从 Spring Initializr 开始

跳过基础知识,请执行以下操作

完成后,可以根据 gs-rest-service/complete 中的代码检查结果。

从 Spring Initializr 开始

可以使用此 预初始化项目,然后单击“生成”下载 ZIP 文件。此项目已配置为适合本教程中的示例。

手动初始化项目

  1. 导航至 https://start.spring.io。此服务会提取应用程序所需的所有依赖项,并为你完成大部分设置。

  2. 选择 Gradle 或 Maven 以及要使用的语言。本指南假定你选择了 Java。

  3. 单击“依赖项”,然后选择“Spring Web”。

  4. 单击“生成”。

  5. 下载生成的 ZIP 文件,该文件是已根据你的选择配置的 Web 应用程序的存档。

如果你的 IDE 集成了 Spring Initializr,则可以从 IDE 完成此过程。
你还可以从 Github 分叉项目,然后在 IDE 或其他编辑器中打开它。

创建资源表示类

现在你已经设置了项目和构建系统,可以创建 Web 服务了。

通过思考服务交互开始此过程。

该服务将处理 /greetingGET 请求,也可以处理查询字符串中带有 name 参数的请求。GET 请求应返回带有 JSON 正文的 200 OK 响应,该 JSON 表示问候语。它应类似于以下输出

{
    "id": 1,
    "content": "Hello, World!"
}

id 字段是问候语的唯一标识符,content 是问候语的文本表示形式。

要对问候语表示进行建模,请创建一个资源表示类。为此,请为 idcontent 数据提供 Java 记录类,如下面的清单所示(来自 src/main/java/com/example/restservice/Greeting.java

package com.example.restservice;

public record Greeting(long id, String content) { }
此应用程序使用 Jackson JSON 库将 Greeting 类型的实例自动编组到 JSON 中。Web 启动器默认包含 Jackson。

创建资源控制器

在 Spring 构建 RESTful Web 服务的方法中,HTTP 请求由控制器处理。这些组件由 @RestController 注释标识,而以下清单(来自 src/main/java/com/example/restservice/GreetingController.java)中显示的 GreetingController 通过返回 Greeting 类的实例来处理 /greetingGET 请求

package com.example.restservice;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

	private static final String template = "Hello, %s!";
	private final AtomicLong counter = new AtomicLong();

	@GetMapping("/greeting")
	public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
		return new Greeting(counter.incrementAndGet(), String.format(template, name));
	}
}

此控制器简洁明了,但其内部却大有乾坤。我们将其逐步分解。

@GetMapping 注解确保对 /greeting 的 HTTP GET 请求映射到 greeting() 方法。

其他 HTTP 动词(例如,POST 的 @PostMapping)有配套的注解。还有一个 @RequestMapping 注解,所有这些注解都派生自该注解,并且可以作为同义词(例如,@RequestMapping(method=GET))。

@RequestParam 将查询字符串参数 name 的值绑定到 greeting() 方法的 name 参数中。如果请求中没有 name 参数,则使用 WorlddefaultValue

方法体的实现创建并返回一个新的 Greeting 对象,该对象具有基于 counter 的下一个值和使用问候语 template 格式化的给定 nameidcontent 属性。

传统 MVC 控制器和前面所示的 RESTful Web 服务控制器之间的主要区别在于创建 HTTP 响应主体的方式。此 RESTful Web 服务控制器填充并返回一个 Greeting 对象,而不是依赖视图技术对问候语数据进行服务器端呈现为 HTML。对象数据将直接写入 HTTP 响应中,作为 JSON。

此代码使用 Spring @RestController 注解,该注解将类标记为控制器,其中每个方法返回域对象,而不是视图。它是同时包含 @Controller@ResponseBody 的简写。

必须将 Greeting 对象转换为 JSON。借助 Spring 的 HTTP 消息转换器支持,您无需手动执行此转换。由于 Jackson 2 位于类路径中,因此 Spring 的 MappingJackson2HttpMessageConverter 会自动选择将 Greeting 实例转换为 JSON。

运行服务

Spring Initializr 为您创建一个应用程序类。在这种情况下,您无需进一步修改类。以下列表(来自 src/main/java/com/example/restservice/RestServiceApplication.java)显示应用程序类

package com.example.restservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RestServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(RestServiceApplication.class, args);
	}

}

@SpringBootApplication 是一个便捷的注解,它添加以下所有内容

  • @Configuration:将类标记为应用程序上下文的 Bean 定义源。

  • @EnableAutoConfiguration:指示 Spring Boot 根据类路径设置、其他 Bean 和各种属性设置开始添加 Bean。例如,如果类路径中存在 spring-webmvc,此注释将标记应用程序为 Web 应用程序并激活关键行为,例如设置 DispatcherServlet

  • @ComponentScan:指示 Spring 在 com/example 包中查找其他组件、配置和服务,以便它找到控制器。

main() 方法使用 Spring Boot 的 SpringApplication.run() 方法启动应用程序。您是否注意到没有一行 XML?也没有 web.xml 文件。此 Web 应用程序是 100% 纯 Java,您不必处理配置任何管道或基础设施。

构建可执行 JAR

您可以使用 Gradle 或 Maven 从命令行运行应用程序。您还可以构建包含所有必需的依赖项、类和资源的单个可执行 JAR 文件并运行它。构建可执行 jar 使得在整个开发生命周期、不同环境中轻松地交付、版本化和部署服务作为应用程序,等等。

如果您使用 Gradle,可以使用 ./gradlew bootRun 运行应用程序。或者,您可以使用 ./gradlew build 构建 JAR 文件,然后运行 JAR 文件,如下所示

java -jar build/libs/gs-rest-service-0.1.0.jar

如果您使用 Maven,可以使用 ./mvnw spring-boot:run 运行应用程序。或者,您可以使用 ./mvnw clean package 构建 JAR 文件,然后运行 JAR 文件,如下所示

java -jar target/gs-rest-service-0.1.0.jar
此处描述的步骤创建可运行 JAR。您还可以 构建经典 WAR 文件

显示日志输出。服务应在几秒钟内启动并运行。

测试服务

现在服务已启动,请访问 https://127.0.0.1:8080/greeting,您应该会看到

{"id":1,"content":"Hello, World!"}

通过访问 https://127.0.0.1:8080/greeting?name=User 提供 name 查询字符串参数。请注意 content 属性的值如何从 Hello, World! 更改为 Hello, User!,如下表所示

{"id":2,"content":"Hello, User!"}

此更改表明 GreetingController 中的 @RequestParam 排列按预期工作。name 参数已赋予默认值 World,但可以通过查询字符串显式覆盖它。

还要注意 id 属性已从 1 变为 2。这证明您跨多个请求针对同一 GreetingController 实例工作,并且其 counter 字段在每次调用时都会按预期递增。

摘要

恭喜!您刚刚使用 Spring 开发了一个 RESTful Web 服务。

获取代码

免费

在云中工作

在 Spring Academy 云中完成本指南。

转到 Spring Academy