本指南将引导您完成创建一个消费 RESTful Web 服务的应用程序的过程。
您将构建什么
您将构建一个应用程序,该应用程序使用 Spring 的 RestTemplate
在 http://localhost:8080/api/random 上检索随机的 Spring Boot 引用。
所需内容
-
大约 15 分钟
-
一个喜欢的文本编辑器或集成开发环境
-
Java 17 或更高版本
-
您也可以直接将代码导入到您的 IDE 中:
如何完成本指南
像大多数 Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以跳过您已经熟悉的基本设置步骤。无论哪种方式,您最终都会得到可运行的代码。
要从头开始,请继续阅读从 Spring Initializr 开始。
要跳过基础知识,请执行以下操作:
-
下载并解压本指南的源代码库,或者使用 Git 克隆它:
git clone https://github.com/spring-guides/gs-consuming-rest.git
-
进入
gs-consuming-rest/initial
目录 -
跳转到 获取 REST 资源。
完成之后,您可以对照 gs-consuming-rest/complete
中的代码检查您的结果。
从 Spring Initializr 开始
您可以使用这个预初始化项目,然后点击生成以下载一个 ZIP 文件。该项目已配置为适合本教程中的示例。
要手动初始化项目:
- 访问 https://start.spring.io。该服务会拉取应用程序所需的所有依赖项,并为您完成大部分设置。
- 选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Java。
- 点击 Dependencies 并选择 Spring Web。
- 点击 Generate。
- 下载生成的 ZIP 文件,这是一个根据您的选择配置好的 Web 应用程序存档。
如果您的 IDE 集成了 Spring Initializr,您可以直接在 IDE 中完成这个过程。
您还可以从 Github 上 fork 这个项目,并在您的 IDE 或其他编辑器中打开它。
获取 REST 资源
完成项目设置后,您可以创建一个简单的应用程序来消费 RESTful 服务。
在此之前,您需要一个 REST 资源的来源。我们在 https://github.com/spring-guides/quoters 提供了一个这样的服务示例。您可以在单独的终端中运行该应用程序,并通过 http://localhost:8080/api/random 访问结果。该地址会随机获取一条关于 Spring Boot 的引用,并将其作为 JSON 文档返回。其他有效的地址包括 http://localhost:8080/api/(获取所有引用)和 http://localhost:8080/api/1(获取第一条引用)、http://localhost:8080/api/2(获取第二条引用),依此类推(目前最多 10 条)。
如果您通过网页浏览器或 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 record 类使用了来自 Jackson JSON 处理库的 @JsonIgnoreProperties
注解,以指示应忽略未在此类型中绑定的任何属性。
要将数据直接绑定到您的自定义类型,您需要将变量名称指定为与 API 返回的 JSON 文档中的键完全相同。如果您的变量名称与 JSON 文档中的键不匹配,您可以使用 @JsonProperty
注解来指定 JSON 文档的确切键。(此示例将每个变量名称与 JSON 键匹配,因此此处不需要该注解。)
您还需要一个额外的类来嵌入内部引语本身。Value
record 类满足了这一需求,并在以下列表(位于 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 源的引用。您需要添加:
-
一个 logger,用于将输出发送到日志(在本例中为控制台)。
-
一个
RestTemplate
,它使用 Jackson JSON 处理库来处理传入的数据。 -
一个
CommandLineRunner
,它在启动时运行RestTemplate
(从而获取我们的引用)。
下面的代码清单展示了完成的 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(
"http://localhost:8080/api/random", Quote.class);
log.info(quote.toString());
};
}
}
最后,您需要设置服务器端口。quotes 应用程序使用了默认的服务器端口 8080,因此这个应用程序不能使用相同的端口。您可以通过在 application properties 文件中(该文件由 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.proxyHost
和http.proxyPort
系统属性设置为适合您环境的值。
总结
恭喜!您刚刚使用 Spring Boot 开发了一个简单的 REST 客户端。
另请参阅
以下指南也可能有所帮助: