原标题:Spring认证指南-了解如何使用 Spring Boot Actuator 创建 RESTful Web 服务。(来源:Spring中国教育管理中心)
Spring认证指南:如何使用 Spring Boot Actuator 创建 RESTful Web 服务
使用 Spring Boot Actuator 构建 RESTful Web 服务
Spring Boot Actuator是 Spring Boot 的一个子项目。它为您的应用程序添加了几项生产级服务,您无需付出任何努力。在本指南中,您将构建一个应用程序,然后了解如何添加这些服务。
你将建造什么
本指南将引导您使用 Spring Boot Actuator 创建“Hello, world” RESTful Web 服务。您将构建一个接受以下 HTTP GET 请求的服务:
$ curl http://localhost:9000/hello-world
它使用以下 JSON 响应:
{“id”:1,“content”:“Hello, World!”}
您的应用程序中还添加了许多功能,用于在生产(或其他)环境中管理服务。您构建的服务的业务功能与构建 RESTful Web 服务中的相同。您无需使用该指南即可利用此指南,尽管比较结果可能会很有趣。
你需要什么
约15分钟
最喜欢的文本编辑器或 IDE
JDK 1.8或更高版本
Gradle 4+或Maven 3.2+
您还可以将代码直接导入 IDE:
弹簧工具套件 (STS)
IntelliJ IDEA
如何完成本指南
像大多数 Spring入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都会得到工作代码。
要从头开始,请继续从 Spring Initializr 开始。
要跳过基础知识,请执行以下操作:
下载并解压本指南的源代码库,或使用Git克隆它:git clone https://github.com/spring-guides/gs-actuator-service.git
光盘进入gs-actuator-service/initial
继续创建一个表示类。
完成后,您可以对照中的代码检查结果
gs-actuator-service/complete。
从 Spring Initializr 开始
您可以使用这个预先初始化的项目并单击 Generate 下载 ZIP 文件。此项目配置为适合本教程中的示例。
手动初始化项目:
导航到https://start.spring.io。该服务提取应用程序所需的所有依赖项,并为您完成大部分设置。
选择 Gradle 或 Maven 以及您要使用的语言。本指南假定您选择了 Java。
单击Dependencies并选择Spring Web和Spring Boot Actuator。
单击生成。
下载生成的 ZIP 文件,该文件是根据您的选择配置的 Web 应用程序的存档。
如果您的 IDE 具有 Spring Initializr 集成,您可以从您的 IDE 完成此过程。
你也可以从 Github 上 fork 项目并在你的 IDE 或其他编辑器中打开它。
运行空服务
Spring Initializr 创建了一个空应用程序,您可以使用它来开始。以下示例(来自目录
src/main/java/com/example/actuatorservice/ActuatorServiceApplication中initial)显示了 Spring Initializr 创建的类:
package com.example.actuatorservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
public class ActuatorServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ActuatorServiceApplication.class, args);
}
}
注释提供了一系列默认值(如@SpringBootApplication嵌入式 servlet 容器),具体取决于类路径的内容和其他内容。它还打开了 Spring MVC 的@EnableWebMvc注解,它激活了 Web 端点。
此应用程序中没有定义端点,但足以启动事物并查看 Actuator 的一些功能。该SpringApplication.run()命令知道如何启动 Web 应用程序。您需要做的就是运行以下命令:
$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
您还没有编写任何代码,那么发生了什么?要查看答案,请等待服务器启动,打开另一个终端,然后尝试以下命令(显示其输出):
$ curl localhost:8080
{“timestamp”:1384788106983,“error”:“Not Found”,“status”:404,“message”:""}
上述命令的输出表明服务器正在运行,但您尚未定义任何业务端点。/error您会看到来自 Actuator端点的通用 JSON 响应,而不是默认的容器生成的 HTML 错误响应。您可以在服务器启动的控制台日志中看到开箱即用的端点。您可以尝试其中一些端点,包括/health端点。以下示例显示了如何执行此操作:
$ curl localhost:8080/actuator/health
{“status”:“UP”}
状态为UP,因此执行器服务正在运行。
有关详细信息,请参阅 Spring Boot 的执行器项目。
创建一个表示类
首先,您需要考虑一下您的 API 会是什么样子。
您想处理 GET 请求/hello-world,可以选择使用名称查询参数。为了响应这样的请求,您想要发回 JSON,表示问候语,如下所示:
{
“id”: 1,
“content”: “Hello, World!”
}
该id字段是问候语的唯一标识符,并content包含问候语的文本表示。
要对问候表示进行建模,请创建一个表示类。以下清单(来自
src/main/java/com/example/actuatorservice/Greeting.java)显示了Greeting该类:
package com.example.actuatorservice;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
现在您需要创建将服务于表示类的端点控制器。
创建资源控制器
在 Spring 中,REST 端点是 Spring MVC 控制器。以下 Spring MVC 控制器(来自
src/main/java/com/example/actuatorservice/HelloWorldController.java)处理/hello-world端点的 GET 请求并返回Greeting资源:
package com.example.actuatorservice;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
public class HelloWorldController {
private static final String template = “Hello, %s!”;
private final AtomicLong counter = new AtomicLong();
@GetMapping("/hello-world")
public Greeting sayHello(@RequestParam(name=“name”, required=false, defaultValue=“Stranger”) String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
面向人类的控制器和 REST 端点控制器之间的主要区别在于如何创建响应。端点控制器不依赖视图(例如 JSP)以 HTML 格式呈现模型数据,而是将要写入的数据直接返回到响应的正文中。
注解告诉 Spring MVC 不要将@ResponseBody模型渲染到视图中,而是将返回的对象写入响应正文中。它通过使用 Spring 的消息转换器之一来实现。因为 Jackson 2 在类路径中,如果请求的标头指定应返回 JSON ,
MappingJackson2HttpMessageConverter则将处理对象到 JSON 的转换。GreetingAccept
你怎么知道 Jackson 2 在类路径上?运行 mvn dependency:tree
或./gradlew dependencies,您将获得包含 Jackson 2.x 的详细依赖树。您还可以看到它来自/spring-boot-starter-json ,它本身由spring-boot-starter-web导入。
运行应用程序
您可以从自定义主类或直接从配置类之一运行应用程序。对于这个简单的示例,您可以使用SpringApplication帮助程序类。请注意,这是 Spring Initializr 为您创建的应用程序类,您甚至无需对其进行修改即可使其适用于这个简单的应用程序。以下清单(来自
src/main/java/com/example/actuatorservice/HelloWorldApplication.java)显示了应用程序类:
package com.example.actuatorservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
在传统的 Spring MVC 应用程序中,您将添加@EnableWebMvc以打开关键行为,包括配置DispatcherServlet. 但是当 Spring Boot 在你的类路径上检测到spring-webmvc时,它会自动打开这个注解。这使您可以在接下来的步骤中构建控制器。
@SpringBootApplication注释还引入了一个注释@ComponentScan,它告诉 Spring 扫描
com.example.actuatorservice包中的那些控制器(以及任何其他带注释的组件类)。
构建一个可执行的 JAR
您可以使用 Gradle 或 Maven 从命令行运行应用程序。您还可以构建一个包含所有必要依赖项、类和资源的单个可执行 JAR 文件并运行它。构建可执行 jar 可以在整个开发生命周期、跨不同环境等中轻松地作为应用程序交付、版本化和部署服务。
如果您使用 Gradle,则可以使用./gradlew bootRun. 或者,您可以使用构建 JAR 文件./gradlew build,然后运行 JAR 文件,如下所示:
java -jar build/libs/gs-actuator-service-0.1.0.jar
如果您使用 Maven,则可以使用./mvnw spring-boot:run. 或者,您可以使用构建 JAR 文件,./mvnw clean package然后运行该 JAR 文件,如下所示:
java -jar 目标/gs-actuator-service-0.1.0.jar
此处描述的步骤创建了一个可运行的 JAR。您还可以构建经典的 WAR 文件。
一旦服务运行(因为您spring-boot:run在终端中运行),您可以通过在单独的终端中运行以下命令来测试它:
$ curl localhost:8080/hello-world
{“id”:1,“content”:“Hello, Stranger!”}
切换到不同的服务器端口
Spring Boot Actuator 默认在端口 8080 上运行。通过添加application.properties文件,您可以覆盖该设置。以下清单(来自
src/main/resources/application.properties)显示了具有必要更改的文件:
server.port: 9000
management.server.port: 9001
management.server.address: 127.0.0.1
通过在终端中运行以下命令再次运行服务器:
$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
该服务现在在端口 9000 上启动。
您可以通过在终端中运行以下命令来测试它是否在端口 9000 上工作:
$ curl localhost:8080/hello-world
curl: (52) Empty reply from server
$ curl localhost:9000/hello-world
{“id”:1,“content”:“Hello, Stranger!”}
$ curl localhost:9001/actuator/health
{“status”:“UP”}
测试您的应用程序
要检查您的应用程序是否工作,您应该为您的应用程序编写单元和集成测试。中的测试类
src/test/java/com/example/actuatorservice/HelloWorldApplicationTests.java确保
您的控制器有响应。
您的管理端点是响应式的。
请注意,测试会在随机端口上启动应用程序。以下清单显示了测试类:
/*
Copyright 2012-2014 the original author or authors.
Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<a href="https://www.apache.org/licenses/LICENSE-2.0" rel="noopener" target="_blank">https://www.apache.org/licenses/LICENSE-2.0</a>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.example.actuatorservice;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.BDDAssertions.then;
/**
Basic integration tests for service demo application.
@author Dave Syer
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {“management.port=0”})
public class HelloWorldApplicationTests {
private int port;
@Value("${local.management.port}")
private int mgt;
private TestRestTemplate testRestTemplate;
public void shouldReturn200WhenSendingRequestToController() throws Exception {
@SuppressWarnings(“rawtypes”)
ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
“http://localhost:” + this.port + “/hello-world”, Map.class);
then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
public void shouldReturn200WhenSendingRequestToManagementEndpoint() throws Exception {
@SuppressWarnings(“rawtypes”)
ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
“http://localhost:” + this.mgt + “/actuator”, Map.class);
then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}
概括
恭喜!您刚刚使用 Spring 开发了一个简单的 RESTful 服务,并使用 Spring Boot Actuator 添加了一些有用的内置服务。