天天看點

Spring認證:了解如何使用 Spring 建立超媒體驅動的 RESTful Web 服務

作者:IT膠囊
Spring認證指南-了解如何使用 Spring 建立超媒體驅動的 RESTful Web 服務。(Spring中國教育管理中心)
Spring認證:了解如何使用 Spring 建立超媒體驅動的 RESTful Web 服務

建構超媒體驅動的 RESTful Web 服務

本指南将引導您完成使用 Spring 建立“Hello, World”超媒體驅動的 REST Web 服務的過程。

超媒體是 REST 的一個重要方面。它使您可以建構在很大程度上解耦用戶端和伺服器的服務,并讓它們獨立發展。為 REST 資源傳回的表示不僅包含資料,還包含指向相關資源的連結。是以,表示的設計對于整體服務的設計至關重要。

你将建造什麼

您将使用 Spring HATEOAS 建構一個超媒體驅動的 REST 服務:一個 API 庫,可用于建立指向 Spring MVC 控制器的連結、建構資源表示并控制如何将它們呈現為支援的超媒體格式(例如 HAL )。

該服務将接受 HTTP GET 請求http://localhost:8080/greeting。

它将以 JSON 表示的問候進行響應,該問候富含最簡單的超媒體元素,即指向資源本身的連結。以下清單顯示了輸出:

{
  "content":"Hello, World!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=World"
    }
  }
}           

響應已經表明您可以使用name查詢字元串中的可選參數自定義問候語,如以下清單所示:

http://localhost:8080/greeting?name=User           

name參數值覆寫預設值World并反映在響應中,如以下清單所示:

{
  "content":"Hello, User!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=User"
    }
  }
}           

你需要什麼

  • 約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-rest-hateoas.git
  • CD光牒進入gs-rest-hateoas/initial
  • 繼續建立資源表示類。

完成後,您可以對照中的代碼檢查結果gs-rest-hateoas/complete。

從 Spring Initializr 開始

您可以使用這個預先初始化的項目并單擊 Generate 下載下傳 ZIP 檔案。此項目配置為适合本教程中的示例。

手動初始化項目:

  1. 導航到https://start.spring.io。該服務提取應用程式所需的所有依賴項,并為您完成大部分設定。
  2. 選擇 Gradle 或 Maven 以及您要使用的語言。本指南假定您選擇了 Java。
  3. 單擊Dependencies并選擇Spring HATEOAS。
  4. 單擊生成。
  5. 下載下傳生成的 ZIP 檔案,該檔案是根據您的選擇配置的 Web 應用程式的存檔。

如果您的 IDE 具有 Spring Initializr 內建,您可以從您的 IDE 完成此過程。

你也可以從 Github 上 fork 項目并在你的 IDE 或其他編輯器中打開它。

添加 JSON 庫

因為您将使用 JSON 來發送和接收資訊,是以您需要一個 JSON 庫。在本指南中,您将使用 Jayway JsonPath 庫。

要在 Maven 建構中包含該庫,請将以下依賴項添加到您的pom.xml檔案中:

<dependency>
  <groupId>com.jayway.jsonpath</groupId>
  <artifactId>json-path</artifactId>
  <scope>test</scope>
</dependency>複制           

以下清單顯示了完成的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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>rest-hateoas-complete</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>rest-hateoas-complete</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-hateoas</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 建構中包含該庫,請将以下依賴項添加到您的build.gradle檔案中:

testCompile 'com.jayway.jsonpath:json-path'複制           

以下清單顯示了完成的build.gradle檔案:

plugins {
	id 'org.springframework.boot' version '2.6.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-hateoas'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
	useJUnitPlatform()
}           

建立資源表示類

現在您已經設定了項目和建構系統,您可以建立您的 Web 服務。

從考慮服務互動開始這個過程。

該服務将公開一個資源/greeting來處理GET請求,可以選擇name在查詢字元串中使用一個參數。該GET請求應200 OK在正文中傳回帶有 JSON 的響應以表示問候。

除此之外,資源的 JSON 表示将通過_links屬性中的超媒體元素清單進行豐富。最基本的形式是指向資源本身的連結。該表示應類似于以下清單:

{
  "content":"Hello, World!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=World"
    }
  }
}           

content是問候語的文本表示。該_links元素包含一個連結清單(在這種情況下,正是一個具有關系類型rel和href指向所通路資源的屬性的連結)。

要對問候表示模組化,請建立一個資源表示類。由于該_links屬性是表示模型的基本屬性,是以 Spring HATEOAS 附帶了一個基類(稱為RepresentationModel),它允許您添加執行個體Link并確定它們如前所示呈現。

建立一個普通的舊 java 對象,該對象擴充RepresentationModel和添加内容的字段和通路器以及構造函數,如以下清單(來自src/main/java/com/example/resthateoas/Greeting.java)所示:

package com.example.resthateoas;

import org.springframework.hateoas.RepresentationModel;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Greeting extends RepresentationModel<Greeting> {

	private final String content;

	@JsonCreator
	public Greeting(@JsonProperty("content") String content) {
		this.content = content;
	}

	public String getContent() {
		return content;
	}
}           
  • @JsonCreator:訓示傑克遜如何建立此 POJO 的執行個體。
  • @JsonProperty:标記傑克遜應該将此構造函數參數放入的字段。

正如您将在本指南後面看到的那樣,Spring 将使用 Jackson JSON 庫将類型的執行個體自動編組Greeting為 JSON。

接下來,建立将提供這些問候語的資源控制器。

建立 REST 控制器

在 Spring 建構 RESTful Web 服務的方法中,HTTP 請求由控制器處理。元件由@RestController注釋辨別,該注釋結合了@Controller和@ResponseBody注釋。以下GreetingController(來自)通過傳回類的新執行個體來src/main/java/com/example/resthateoas/GreetingController.java處理GET請求:/greetingGreeting

package com.example.resthateoas;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@RestController
public class GreetingController {

	private static final String TEMPLATE = "Hello, %s!";

	@RequestMapping("/greeting")
	public HttpEntity<Greeting> greeting(
		@RequestParam(value = "name", defaultValue = "World") String name) {

		Greeting greeting = new Greeting(String.format(TEMPLATE, name));
		greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel());

		return new ResponseEntity<>(greeting, HttpStatus.OK);
	}
}           

這個控制器簡潔明了,但是有很多事情要做。我們一步一步分解。

@RequestMapping注釋確定 HTTP 請求/greeting映射到greeting()方法。

上面的例子沒有指定GETvs. PUT,POST等等,因為預設@RequestMapping映射所有的 HTTP 操作。用于@GetMapping("/greeting")縮小此映射。在這種情況下,您還想import org.springframework.web.bind.annotation.GetMapping;.

@RequestParam将查詢字元串參數的值綁定name到方法的name參數中greeting()。這個查詢字元串參數隐含不是required因為使用了defaultValue屬性。如果請求中不存在,則使用defaultValueof World。

因為@RestController注釋存在于類上,是以将隐式@ResponseBody注釋添加到greeting方法中。這會導緻 Spring MVC 将傳回HttpEntity的及其有效負載 (the Greeting) 直接呈現給響應。

方法實作中最有趣的部分是如何建立指向控制器方法的連結以及如何将其添加到表示模型中。兩者linkTo(…)和methodOn(…)都是靜态方法,ControllerLinkBuilder可讓您僞造控制器上的方法調用。傳回的LinkBuilder将檢查控制器方法的映射注釋以準确建構該方法映射到的 URI。

Spring HATEOAS 尊重各種X-FORWARDED-标頭。如果您将 Spring HATEOAS 服務放在代理後面并使用标頭正确配置它X-FORWARDED-HOST,則生成的連結将被正确格式化。

調用withSelfRel()建立Link您添加到Greeting表示模型的執行個體。

@SpringBootApplication是一個友善的注釋,它添加了以下所有内容:

  • @Configuration: 将類标記為應用程式上下文的 bean 定義源。
  • @EnableAutoConfiguration:告訴 Spring Boot 根據類路徑設定、其他 bean 和各種屬性設定開始添加 bean。例如,如果spring-webmvc位于類路徑上,則此注釋将應用程式标記為 Web 應用程式并激活關鍵行為,例如設定DispatcherServlet.
  • @ComponentScan: 告訴 Spring 在包中查找其他元件、配置和服務com/example,讓它找到控制器。

該main()方法使用 Spring Boot 的SpringApplication.run()方法來啟動應用程式。您是否注意到沒有一行 XML?也沒有web.xml檔案。這個 Web 應用程式是 100% 純 Java,您不必處理任何管道或基礎設施的配置。

建構一個可執行的 JAR

您可以使用 Gradle 或 Maven 從指令行運作應用程式。您還可以建構一個包含所有必要依賴項、類和資源的單個可執行 JAR 檔案并運作它。建構可執行 jar 可以在整個開發生命周期、跨不同環境等中輕松地作為應用程式傳遞、版本化和部署服務。

如果您使用 Gradle,則可以使用./gradlew bootRun. 或者,您可以使用建構 JAR 檔案./gradlew build,然後運作 ​JAR 檔案,如下所示:

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

如果您使用 Maven,則可以使用./mvnw spring-boot:run. 或者,您可以使用建構 JAR 檔案,./mvnw clean package然後運作該 JAR 檔案,如下所示:

java -jar 目标/gs-rest-hateoas-0.1.0.jar           

此處描述的步驟建立了一個可運作的 JAR。您還可以建構經典的 WAR 檔案。

顯示記錄輸出。該服務應在幾秒鐘内啟動并運作。

測試服務

現在服務已經啟動,通路http://localhost:8080/greeting,您應該會看到以下内容:

{
  "content":"Hello, World!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=World"
    }
  }
}           

name通過通路以下 URL提供查詢字元串參數: http://localhost:8080/greeting?name=User。請注意屬性的值如何content從Hello, World!to更改,Hello, User!并且連結的href屬性也self反映了該更改,如以下清單所示:

{
  "content":"Hello, User!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting?name=User"
    }
  }
}           

這一變化表明,@RequestParam安排GreetingController按預期工作。該name參數已被賦予預設值,World但始終可以通過查詢字元串顯式覆寫。

概括

恭喜!您剛剛使用 Spring HATEOAS 開發了一個超媒體驅動的 RESTful Web 服務。