使用 Spring Boot Actuator 构建 RESTful Web 应用
Spring Boot Actuator 是 Spring Boot 的一个子项目。通过它,可以很轻易地为应用提供多种生产级服务。本教程中,你将通过构建一个应用来学习如何添加这些服务。
1. 你需要构建什么
本教程将带你使用 Spring Boot Actuator 创建一个 “hello world” RESTful Web 服务。你需要构建一个 HTTP GET 请求服务:
$ curl http://localhost:9000/hello-world
复制代码
返回以下 JSON:
{"id":1,"content":"Hello, World!"}
复制代码
它们也向你的应用中增加了很多开箱即用的、可在生产(或其他)环境管理服务的功能。你所构建的服务,其业务功能与 构建 RESTful Web 应用 教程结果相一致。尽管比较结果可能很有趣,但也无需为了学习而学习此教程。
1.1. 你需要准备什么
- 大约 15 分钟时间
- 一个喜欢的 IDE 或文本编辑器
- JDK 1.8 或更高版本
- Gradle 4+ 或 Maven 3.2+
- 还可以直接将代码导入到 IDE 中:
2. 如何完成本教程
像大多数 Spring 入门指南 一样,你可以从头开始并完成每一步,也可以跳过已经熟悉的基础配置环节。无论如何,最终都会得到可正常工作的代码。
从头开始,请移步 使用 Gradle 构建 章节
跳过基础环节,请执行以下步骤:
- 下载 并解压本教程的源代码,或使用 Git 进行 clone:
git clone https://github.com/spring-guides/gs-actuator-service.git
- 进入
gs-actuator-service/initial
目录 - 向前跳转至 创建表现类 章节
结束后,可以根据 gs-actuator-service/complete
目录下的代码来检查结果。
3. 使用 Gradle 构建
首先,设置一个基本的构建脚本。在使用 Spring 构建应用时,可以使用任何你喜欢的构建程序。此处包含的代码需要通过 Gradle 或 Maven 来运行。如果还不熟悉它们,请参阅 使用 Gradle 构建 Java 项目 或 使用 Maven 构建 Java 项目。
3.1. 创建目录结构
在工作目录中,创建如下所示的子目录结构;例如,在类 UNIX 系统中,可使用 mkdir -p src/main/java/hello
命令创建。
└── src
└── main
└── java
└── hello
复制代码
3.2. 创建 Gradle 构建脚本
下面是 Gradle 初始化构建脚本:
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-actuator-service'
version = '0.1.0'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
testCompile("org.springframework.boot:spring-boot-starter-test")
testCompile("junit:junit")
}
复制代码
Spring Boot Gradle 插件 提供了很多方便的功能:
- 汇集 classpath 下的所有 jar 包依赖,并构建一个可执行的单体 “über-jar”,这将使执行和传输你的服务变得更加方便。
- 搜索
public static void main()
方法所在的类,并将其标记为可执行类。 - 提供一个内置有 Spring Boot 依赖 匹配版本号集合的依赖解析器。你也可以重写为任意版本,但它默认为 Spring Boot 所选的版本号集合。
4. 使用 Maven 构建
首先,设置一个基本的构建脚本。在使用 Spring 构建应用时,可以使用任何你喜欢的构建程序。此处包含的代码需要通过 Maven 来运行。如果还不熟悉它,请参阅 使用 Maven 构建 Java 项目。
4.1. 创建目录结构
在工作目录中,创建如下所示的子目录结构;例如,在类 UNIX 系统中,可使用 mkdir -p src/main/java/hello
命令创建。
└── src
└── main
└── java
└── hello
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-actuator-service</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
Spring Boot Maven 插件 提供了很多方便的功能:
- 汇集 classpath 下的所有 jar 包依赖,并构建一个可执行的单体 “über-jar”,这使得执行和传输你的服务变得更加方便。
- 搜索
public static void main()
方法所在的类,并将其标记为可执行类。 - 提供一个内置有 Spring Boot 依赖 匹配版本号集合的依赖解析器。你也可以重写为任意版本,但它默认为 Spring Boot 所选的版本号集合。
5. 使用 IDE 构建
- 阅读如何将本教程代码直接导入到 Spring Tool Suite
- 阅读如何在 IntelliJ IDEA 中使用本教程代码
6. 运行空服务
对初学者来说,这儿有一个空白的 Spring MVC 应用。
src/main/java/hello/HelloWorldApplication.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
复制代码
@SpringBootApplication
注解提供了一些默认值(如嵌入式 Servlet 容器),当然,这取决于你 classpath 下的内容和其他内容。同时,还开启了 Spring MVC 的 @EnableWebMvc
注解,以激活 Web 端点。
程序中没有定义任何端点,但它已足够启动并观察 Actuator 的一些功能。 SpringApplication.run()
命令知道如何启动 Web 应用。你只需要运行此命令即可。
$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
复制代码
你几乎没有写任何代码,结果会发生什么?等服务启动好之后,打开另一个 Terminal 终端来进行测试:
$ curl localhost:8080
{"timestamp":1384788106983,"error":"Not Found","status":404,"message":""}
复制代码
服务器正在运行,而你并未定义任何业务端点。你可以看到来自 Actuator /error
端点的通用 JSON 响应,而不是容器默认生成的 HTML 错误响应 。你可在服务启动的控制台日志中看到暴露出来了哪些开箱即用的端点。例如:
$ curl localhost:8080/actuator/health
{"status":"UP"}
复制代码
很好,服务已然 “UP”。
查看 Spring Boot Actuator 工程 以了解更多详情。
7. 创建表现类
首先,考虑一下你的 API 会是什么样子。
你希望处理 /hello-world
的 GET 请求时,可以使用 name 查询参数。为了响应这样的请求,你将返回如下所示的 JSON 来代表一个问候语。
{
"id": 1,
"content": "Hello, World!"
}
复制代码
id
字段是问候语的唯一标识,content
字段则是问候语的文本表示。
创建一个表示类来对问候语表示进行建模:
src/main/java/hello/Greeting.java
package hello;
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;
}
}
复制代码
现在,你可以创建一个为表现类服务的控制器端点。
8. 创建资源控制器
在 Spring 中,REST 端点就是 Spring MVC 控制器。下面的 Spring MVC 控制器处理了 /hello-world
的 GET 请求,并返回 Greeting
资源:
src/main/java/hello/HelloWorldController.java
package hello;
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;
@Controller
public class HelloWorldController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@GetMapping("/hello-world")
@ResponseBody
public Greeting sayHello(@RequestParam(name="name", required=false, defaultValue="Stranger") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
复制代码
面向用户的控制器和 REST 端点控制器的关键区别在于如何创建响应。端点控制器不依赖视图(例如JSP)来渲染 HTML 中的模型数据,而是简单地将要写入的数据直接返回到响应体中。
@ResponseBody
注解告诉 Spring MVC 不要将模型渲染到视图中,而是将要返回的对象写入响应体。渲染这一步骤将通过 Spring 消息转换器来实现。Jackson 2 已在 classpath 中,这意味着,如果 Accept
请求头指定应该返回 JSON,MappingJackson2HttpMessageConverter
将处理 Greeting 到 JSON 之间的转换。
如何知道 Jackson 2 在 classpath 中呢?运行
mvn dependency:tree
或./gradlew dependencues
命令,将得到详细的依赖树,并将显示 Jackson 2.x。你还可以看到它来自于 spring-boot-starter-json,其则是由 spring-boot-starter-web 依赖导入。
9. 创建可执行的 main 类
你可以从自定义主类启动应用,或者也可以直接从其中一个配置类执行此操作。最简单的办法就是使用 SpringApplication
辅助类:
src/main/java/hello/HelloWorldApplication.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
复制代码
在传统 Spring MVC 应用中,你需要通过添加 @EnableWebMvc
注解来打开包括 DispatcherServlet
在内的关键特性。当 Spring Boot 在 classpath 中检测到 spring-webmvc 时,会自动打开此注解。这将使你在接下来的步骤中可以更方便地构建控制器。
@SpringBootApplication
还引入了 @ComponentSacn
注解,来告诉 Spring 扫描 hello
包,并加载那些控制器(以及其他被标注了注解的组件类)。
10. 构建可执行 JAR
你可以在命令行中通过 Gradle 或 Maven 来运行应用,也可以构建并运行一个包含了必要依赖、类和资源文件的可执行 JAR 包。这将使在整个开发生命周期中,跨不同环境应用程序发布、版本和部署更为容易。
如果你使用的是 Gradle,可以通过 ./gradlew bootRun
来启动应用;也可通过 ./gradlew build
来构建 JAR 包,并通过下述命令运行之:
java -jar build/libs/gs-actuator-service-0.1.0.jar
复制代码
如果你使用的是 Maven,可以通过 ./mvnw spring-boot:run
来启动应用;也可通过 ./mvnw clean package
来构建 JAR 包,并通过下述命令运行之:
java -jar target/gs-actuator-service-0.1.0.jar
复制代码
上述两种方式将创建一个可执行 JAR 包,你也可以 构建一个经典 WAR 包。
... service comes up ...
复制代码
测试一下:
$ curl localhost:8080/hello-world
{"id":1,"content":"Hello, Stranger!"}
复制代码
11. 切换到其他端口
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
... service comes up on port 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"}
复制代码
12. 测试应用
为了检查应用程序是否可以正常运行,你应该编写应用程序的单元/集成测试类。可参照下面测试案例:
- 控制器是否正常
- 管理端点是否正常
正如在测试类中所看到的那样,我们在随机端口启动应用。
src/test/java/hello/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
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* 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 hello;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
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 org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.BDDAssertions.then;
/**
* Basic integration tests for service demo application.
*
* @author Dave Syer
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {"management.port=0"})
public class HelloWorldApplicationTests {
@LocalServerPort
private int port;
@Value("${local.management.port}")
private int mgt;
@Autowired
private TestRestTemplate testRestTemplate;
@Test
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);
}
@Test
public void shouldReturn200WhenSendingRequestToManagementEndpoint() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
"http://localhost:" + this.mgt + "/actuator/info", Map.class);
then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}
复制代码
13. 总结
恭喜你,你已用 Spring 开发了一个简单的 RESTful 服务。正因为 Spring Boot Actuator,你添加了一些有用的内置服务。
14. 参考
以下教程也可能对你有所帮助:
想要撰写新的教程或者是为现有的教程进行完善?请查看我们的 贡献指南。
所有已发布的教程均为代码提供 ASLv2 许可协议,为正文提供 CC BY-ND 3.0 许可协议。
作者:spring.io
译者:万想
使用 Spring Boot Actuator 构建 RESTful Web 应用的更多相关文章
- SpringBoot实战(十)之使用Spring Boot Actuator构建RESTful Web服务
一.导入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...
- [原创]Spring boot 框架构建jsp web应用
说明 Spring boot支持将web项目打包成一个可执行的jar包,内嵌tomcat服务器,独立部署 为支持jsp,则必须将项目打包为war包 pom.xml中设置打包方式 <packagi ...
- 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务
原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/ 简介: Spring,构建 Java™ 平台和 Enterprise Edition ...
- Spring Boot实战:Restful API的构建
上一篇文章讲解了通过Spring boot与JdbcTemplate.JPA和MyBatis的集成,实现对数据库的访问.今天主要给大家分享一下如何通过Spring boot向前端返回数据. 在现在的开 ...
- Spring - Spring Boot - Actuator Web 访问开启
1. 概述 打开 Spring Boot Actuator 的 Web 访问 2. 场景 之前看 Spring 的时候, 曾经想了解当时的配置 后来发现, 确实有这么个工具 刚开始发现, 除了 act ...
- spring boot actuator专题
spring-boot-starter-actuator模块的实现对于实施微服务的中小团队来说,可以有效地减少监控系统在采集应用指标时的开发量.当然,它也并不是万能的,有时候我们也需要对其做一些简单的 ...
- Spring - Spring Boot - 应用构建与运行
概述 spring boot 应用构建 spring boot 应用运行 背景 之前的看了看 Spring 的书, 结果老懒没实践 而且后续有别的想法, 但这个始终是第一步 1. 准备 知识 java ...
- 使用 Spring Boot 快速构建 Spring 框架应用--转
原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/ Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2 ...
- 使用 Spring Boot 快速构建 Spring 框架应用,PropertyPlaceholderConfigurer
Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2002 年发布以来,Spring 框架已经成为企业应用开发领域非常流行的基础框架.有大量的企业应用基于 Spring 框架来开发.S ...
随机推荐
- hudson绑定svn和vs2008实现持续构建
作者:朱金灿 来源:http://blog.csdn.net/clever101 首先需要在服务器上安装以下工具: (1)hudson,我推荐从http://hudson-ci.org/downloa ...
- 配置文件——App.config文件读取和修改
作为普通的xml文件读取的话,首先就要知道怎么寻找文件的路径.我们知道一般配置文件就在跟可执行exe文件在同一目录下,且仅仅在名称后面添加了一个.config 因此,可以用Application.Ex ...
- hdu - 4971 - A simple brute force problem.(最大权闭合图)
题意:n(n <= 20)个项目,m(m <= 50)个技术问题,做完一个项目能够有收益profit (<= 1000),做完一个项目必须解决对应的技术问题,解决一个技术问题须要付出 ...
- Gradle Android它自己的编译脚本教程的最新举措(提供demo源代码)
一.前言 Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自己主动化构建工具. 上面这句话我认为写得非常官方,大家仅仅需知道Gradle能够用来an ...
- IOC DI SL的一些理论
本文来自圣杰的简书 圣杰 yubinfeng的 这篇文章也很不错 很简单
- MySQL SYS CPU高的案例分析(一)
原文:MySQL SYS CPU高的案例分析(一) [现象] 最近关注MySQL CPU告警的问题时,发现有一种场景,有一些服务器最近都较频繁的出现CPU告警,其中的现象是 SYS CPU占比较高. ...
- 计算机程序设计的史诗TAOCP
倘若你去问一个木匠学徒:你需要什么样的工具进行工作,他可能会回答你:“我只要一把锤子和一个锯”.但是如果你去问一个老木工或者是大师级的建筑师,他会告诉你“我需要一些精确的工具”.由于计算机所解决的问题 ...
- WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化
原文:WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化 注:最近在做3D机械模型重建方面的软件,需要根据光栅传感器采集的数据绘制3D图形,并显示出色差以及 ...
- mac_开发机初始化环境
#安装 homebrew 类似 yum ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/ma ...
- WCF学习目录
WCF 基本 WCF概念 WCF配置文件详解 多个不同类对象传输思路 WCF 大文件传输配置 Uri ? & = 毫秒数据字符串转换为DateTime POST请求——HttpWebReque ...