使用 RESTful Web 服务

本指南将引导您完成创建使用 RESTful Web 服务的应用程序的过程。

您将构建什么

您将构建一个使用 Spring 的 RestTemplatehttps://127.0.0.1:8080/api/random 检索随机 Spring Boot 引用的应用程序。

您需要什么

如何完成本指南

与大多数 Spring 入门指南 一样,您可以从头开始完成每个步骤,也可以跳过您已经熟悉的设置步骤。无论哪种方式,您最终都会获得可用的代码。

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

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

完成之后,可以将结果与 gs-consuming-rest/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 或其他编辑器中将其打开。

获取 REST 资源

项目设置完成后,您可以创建一个使用 RESTful 服务的简单应用程序。

在执行此操作之前,您需要一个 REST 资源源。我们已在 https://github.com/spring-guides/quoters 中提供了此类服务的示例。您可以在单独的终端中运行该应用程序,并在 https://127.0.0.1:8080/api/random 中访问结果。该地址会随机获取有关 Spring Boot 的引用,并将其作为 JSON 文档返回。其他有效地址包括 https://127.0.0.1:8080/api/(用于所有引用)和 https://127.0.0.1:8080/api/1(用于第一个引用)、https://127.0.0.1:8080/api/2(用于第二个引用),依此类推(目前最多为 10 个)。

如果您通过 Web 浏览器或 curl 请求该 URL,您会收到一个类似于此的 JSON 文档

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}

通过浏览器或 curl 获取时,这足够简单,但并不是特别有用。

以编程方式使用 REST Web 服务是一种更有用的方式。为了帮助您完成此任务,Spring 提供了一个名为 RestTemplate 的便捷模板类。RestTemplate 使与大多数 RESTful 服务交互成为一行咒语。它甚至可以将该数据绑定到自定义域类型。

首先,您需要创建一个域类来包含您需要的数据。以下清单显示了 Quote 记录类,您可以将其用作您的域类

src/main/java/com/example/consumingrest/Quote.java

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record Quote(String type, Value value) { }

此简单的 Java 记录类使用 Jackson JSON 处理库的 @JsonIgnoreProperties 进行注释,以指示不绑定在此类型中的任何属性都应被忽略。

要将您的数据直接绑定到您的自定义类型,您需要指定变量名称与 API 返回的 JSON 文档中的键完全相同。如果您的变量名称和 JSON 文档中的键不匹配,您可以使用 @JsonProperty 注释来指定 JSON 文档的确切键。(此示例将每个变量名称与一个 JSON 键匹配,因此您此处不需要该注释。)

您还需要一个附加类来嵌入内部引号本身。Value 记录类满足该需求,并在以下清单中显示(在 src/main/java/com/example/consumingrest/Value.java

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record Value(Long id, String quote) { }

这使用相同的注释,但映射到其他数据字段。

完成应用程序

Initializr 创建一个带有 main() 方法的类。以下清单显示了 Initializr 创建的类(在 src/main/java/com/example/consumingrest/ConsumingRestApplication.java

package com.example.consumingrest;

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

@SpringBootApplication
public class ConsumingRestApplication {

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

}

现在,您需要向 ConsumingRestApplication 类添加一些其他内容,以使其显示来自我们的 RESTful 源的引号。您需要添加

  • 一个记录器,用于将输出发送到日志(在此示例中为控制台)。

  • 一个 RestTemplate,它使用 Jackson JSON 处理库来处理传入的数据。

  • 一个在启动时运行 RestTemplate(因此获取我们的引号)的 CommandLineRunner

以下清单显示了完成的 ConsumingRestApplication 类(在 src/main/java/com/example/consumingrest/ConsumingRestApplication.java

package com.example.consumingrest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumingRestApplication {

	private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

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

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}

	@Bean
	@Profile("!test")
	public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
		return args -> {
			Quote quote = restTemplate.getForObject(
					"https://127.0.0.1:8080/api/random", Quote.class);
			log.info(quote.toString());
		};
	}
}

最后,您需要设置服务器端口。quoters 应用程序使用默认服务器端口 8080,因此此应用程序也不能使用相同的端口。您可以通过将以下行添加到应用程序属性(Initializr 为您创建的)将服务器端口设置为 8081

server.port=8081

运行应用程序

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

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

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

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

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

你应该看到类似于以下内容的输出,但带有随机引号

2019-08-22 14:06:46.506  INFO 42940 --- [           main] c.e.c.ConsumingRestApplication           : Quote{type='success', value=Value{id=1, quote='Working with Spring Boot is like pair-programming with the Spring developers.'}}
如果你看到一条错误消息,内容为 Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.consumingrest.Quote],则你可能处于无法连接到后端服务(如果你能访问它,它会发送 JSON)的环境中。也许你处于公司代理后面。尝试将 http.proxyHosthttp.proxyPort 系统属性设置为适合你环境的值。

摘要

恭喜!你刚刚使用 Spring Boot 开发了一个简单的 REST 客户端。

获取代码