# 使用Spring Boot Actuator構建RESTful Web服務
[Spring Boot Actuator Spring Boot](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready) 是 的子項目。 它為您的應用程序增加了幾項生產級服務,而您卻毫不費力。 在本指南中,您將構建一個應用程序,然后查看如何添加這些服務。
## 你會建立什么
本指南將指導您使用Spring Boot Actuator創建一個“世界,您好”的RESTful Web服務。 您將構建一個接受以下HTTP GET請求的服務:
~~~
$ curl http://localhost:9000/hello-world
~~~
它使用以下JSON進行響應:
~~~
{"id":1,"content":"Hello, World!"}
~~~
您的應用程序中還添加了許多功能,用于在生產(或其他)環境中管理服務。 您構建的服務的業務功能與構建 [RESTful Web服務中的功能相同](https://spring.io/guides/gs/rest-service) 。 盡管比較結果可能會很有趣,但是您無需使用該指南即可利用這一指南。
### 你需要什么
* 約15分鐘
* 最喜歡的文本編輯器或IDE
* [JDK 1.8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 或更高版本
* [Gradle 4+](http://www.gradle.org/downloads) 或 [Maven 3.2+](https://maven.apache.org/download.cgi)
* 您還可以將代碼直接導入到IDE中:
* [彈簧工具套件(STS)](https://spring.io/guides/gs/sts)
* [IntelliJ IDEA](https://spring.io/guides/gs/intellij-idea/)
## 如何完成本指南
像大多數Spring 一樣 [入門指南](https://spring.io/guides) ,您可以從頭開始并完成每個步驟,也可以繞過您已經熟悉的基本設置步驟。 無論哪種方式,您最終都可以使用代碼。
要 **從頭開始** ,請繼續進行“ [從Spring Initializr開始”](https://spring.io/guides/gs/actuator-service/#scratch) 。
要 **跳過基礎知識** ,請執行以下操作:
* [下載](https://github.com/spring-guides/gs-actuator-service/archive/master.zip) 并解壓縮本指南的源存儲庫,或使用 對其進行克隆 [Git](https://spring.io/understanding/Git) : `git clone [https://github.com/spring-guides/gs-actuator-service.git](https://github.com/spring-guides/gs-actuator-service.git)`
* 光盤進入 `gs-actuator-service/initial`
* 繼續 [創建代表類](https://spring.io/guides/gs/actuator-service/#initial) 。
**完成后** ,您可以根據中的代碼檢查結果 `gs-actuator-service/complete`.
## 從Spring Initializr開始
如果您使用Maven,請訪問 [Spring Initializr](https://start.spring.io/#!type=maven-project&language=java&platformVersion=2.4.3.RELEASE&packaging=jar&jvmVersion=1.8&groupId=com.example&artifactId=actuator-service&name=actuator-service&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.actuator-service&dependencies=web,actuator) 以生成具有所需依賴項的新項目(Spring Web和Spring Boot Actuator)。
以下清單顯示了 `pom.xml` 選擇Maven時創建的文件:
~~~
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>actuator-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>actuator-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
~~~
如果使用Gradle,請訪問 [Spring Initializr](https://start.spring.io/#!type=gradle-project&language=java&platformVersion=2.4.3.RELEASE&packaging=jar&jvmVersion=1.8&groupId=com.example&artifactId=actuator-service&name=actuator-service&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.actuator-service&dependencies=web,actuator) 以生成具有所需依賴項的新項目(Spring Web和Spring Boot Actuator)。
以下清單顯示了 `build.gradle`選擇Gradle時創建的文件:
~~~
plugins {
id 'org.springframework.boot' version '2.4.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
~~~
### 手動初始化(可選)
如果要手動初始化項目而不是使用前面顯示的鏈接,請按照以下步驟操作:
1. 導航到 [https://start.spring.io](https://start.spring.io) 。 該服務提取應用程序所需的所有依賴關系,并為您完成大部分設置。
2. 選擇Gradle或Maven以及您要使用的語言。 本指南假定您選擇了Java。
3. 單擊 **Dependencies,** 然后選擇 **Spring Web** 和 **Spring Boot Actuator** 。
4. 點擊 **生成** 。
5. 下載生成的ZIP文件,該文件是使用您的選擇配置的Web應用程序的存檔。
如果您的IDE集成了Spring Initializr,則可以從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;
@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":""}
~~~
前面命令的輸出表明服務器正在運行,但是您尚未定義任何業務端點。 您會看到執行器發出的通用JSON響應,而不是默認的容器生成的HTML錯誤響應 `/error`端點。 您可以在服務器啟動的控制臺日志中看到開箱即用提供的端點。 您可以嘗試其中的一些端點,包括 `/health`端點。 以下示例顯示了如何執行此操作:
~~~
$ curl localhost:8080/actuator/health
{"status":"UP"}
~~~
狀態為 `UP`,因此執行器服務正在運行。
有關 請參見Spring Boot的 [Actuator Project](https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-actuator) 更多詳細信息, 。
## 創建一個表示形式類
首先,您需要考慮一下API的外觀。
您要處理GET請求 `/hello-world`,可以選擇使用名稱查詢參數。 為了響應這樣的請求,您想發送回表示問候的JSON,該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`)處理GET請求, `/hello-world` 端點并返回 `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;
@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`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html)批注告訴Spring MVC不要將模型呈現到視圖中,而是將返回的對象寫到響應主體中。 它是通過使用Spring的消息轉換器之一來實現的。 因為Jackson 2在類路徑中, [`MappingJackson2HttpMessageConverter`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.html) 將處理 `Greeting` 如果請求的是JSON對象 `Accept` 標頭指定應返回JSON。
您怎么知道杰克遜2正在上課? 運行`mvndependency: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;
@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`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html) 批注,告訴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 target/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
*
* 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 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 {
@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);
}
}
~~~
## 概括
恭喜你! 您剛剛使用Spring開發了一個簡單的RESTful服務,并且使用Spring Boot Actuator添加了一些有用的內置服務。
- springboot概述
- springboot構建restful服務
- spring構建一個RESTful Web服務
- spring定時任務
- 消費RESTful Web服務
- gradle構建項目
- maven構建項目
- springboot使用jdbc
- springboot應用上傳文件
- 使用LDNA驗證用戶
- 使用 spring data redis
- 使用 spring RabbitTemplate消息隊列
- 用no4j訪問nosql數據庫
- springboot驗證web表單
- Spring Boot Actuator構j建服務
- 使用jms傳遞消息
- springboot創建批處理服務
- spring security保護web 安全
- 在Pivotal GemFire中訪問數據
- 使用Spring Integration
- 使用springboot jpa進行數據庫操作
- 數據庫事務操作
- 操作mongodb
- springmvc+tymleaf創建web應用
- 將Spring Boot JAR應用程序轉換為WAR
- 創建異步服務
- spring提交表單
- 使用WebSocket構建交互式Web應用程序
- 使用REST訪問Neo4j數據
- jquery消費restful
- springboot跨域請求
- 消費SOAP Web服務
- springboot使用緩存
- 使用Vaadin創建CRUD UI
- 使用REST訪問JPA數據
- 使用REST訪問Pivotal GemFire中的數據
- 構建soap服務
- 使用rest訪問mongodb數據
- 構建springboot應用docker鏡像
- 從STS部署到Cloud Foundry
- springboot測試web應用
- springboot訪問mysql
- springboot編寫自定義模塊并使用
- 使用Google Cloud Pub / Sub進行消息傳遞
- 構建反應式RESTful Web服務
- 使用Redis主動訪問數據
- Spring Boot 部署到Kubernetes
- 使用反應式協議R2DBC訪問數據
- Spring Security架構
- spring構建Docker鏡像詳解
- Spring Boot和OAuth2
- springboot應用部署到k8s
- spring構建rest服務詳解