全球動態:使用 Spring 創建“Hello, World”RESTful Web 服務的過程

2022-12-22 16:21:02 來源:51CTO博客

本指南將引導您完成使用 Spring 創建“Hello, World”RESTful Web 服務的過程,該服務在響應中包含跨域資源共享 (CORS) 的標頭。您可以在此中找到有關Spring CORS支持的更多信息博客文章.


【資料圖】

您將構建什么

您將構建一個服務,該服務接受 HTTP GET 請求并使用問候語的 JSON 表示形式進行響應,如以下列表所示:??http://localhost:8080/greeting??

{"id":1,"content":"Hello, World!"}

可以使用查詢字符串中的可選參數自定義問候語,如以下清單所示:??name??

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

參數值將覆蓋 的默認值,并反映在響應中,如以下清單所示:??name????World??

{"id":1,"content":"Hello, User!"}

此服務與 中所述的服務略有不同構建一個 RESTful Web 服務,因為它使用 Spring 框架 CORS 支持來添加相關的 CORS 響應標頭。

你需要什么

約15分鐘最喜歡的文本編輯器或 IDEJDK 1.8或以后格拉德爾 4+?或梅文 3.2+您也可以將代碼直接導入到 IDE 中:彈簧工具套件 (STS)智能理念VSCode

如何完成本指南

像大多數春天一樣入門指南,您可以從頭開始并完成每個步驟,也可以繞過您已經熟悉的基本設置步驟。無論哪種方式,您最終都會得到工作代碼。

要從頭開始,請繼續從 Spring 初始化開始.

要跳過基礎知識,請執行以下操作:

下載?并解壓縮本指南的源存儲庫,或使用吉特:git clonehttps://github.com/spring-guides/gs-rest-service-cors.git光盤成gs-rest-service-cors/initial跳轉到創建資源表示類.

完成后,您可以根據 中的代碼檢查結果。??gs-rest-service-cors/complete??

從 Spring 初始化開始

你可以使用這個預初始化項目,然后單擊生成以下載 ZIP 文件。此項目配置為適合本教程中的示例。

手動初始化項目:

導航到https://start.spring.io.此服務拉入應用程序所需的所有依賴項,并為您完成大部分設置。選擇 Gradle 或 Maven 以及您要使用的語言。本指南假定您選擇了 Java。單擊“依賴關系”,然后選擇“Spring Web”。單擊生成。下載生成的 ZIP 文件,該文件是配置了您選擇的 Web 應用程序的存檔。

如果您的 IDE 集成了 Spring Initializr,則可以從 IDE 完成此過程。

您也可以從 Github 分叉項目,然后在 IDE 或其他編輯器中打開它。

添加依賴項??httpclient??

測試(在)需要Apache庫。??complete/src/test/java/com/example/restservicecors/GreetingIntegrationTests.java????httpclient??

要將 Apache 庫添加到 Maven,請添加以下依賴項:??httpclient??

  org.apache.httpcomponents  httpclient  test

以下清單顯示了完成的文件:??pom.xml??

  4.0.0      org.springframework.boot    spring-boot-starter-parent    3.0.0         com.example  rest-service-cors-complete  0.0.1-SNAPSHOT  rest-service-cors-complete  Demo project for Spring Boot      17              org.springframework.boot      spring-boot-starter-web              org.apache.httpcomponents.client5      httpclient5      test              org.springframework.boot      spring-boot-starter-test      test                          org.springframework.boot        spring-boot-maven-plugin            

要將 Apache 庫添加到 Gradle,請添加以下依賴項:??httpclient??

testImplementation "org.apache.httpcomponents:httpclient"

以下清單顯示了完成的文件:??build.gradle??

plugins {  id "org.springframework.boot" version "3.0.0"  id "io.spring.dependency-management" version "1.1.0"  id "java"}group = "com.example"version = "0.0.1-SNAPSHOT"sourceCompatibility = "17"repositories {  mavenCentral()}dependencies {  implementation "org.springframework.boot:spring-boot-starter-web"  testImplementation "org.apache.httpcomponents.client5:httpclient5"  testImplementation "org.springframework.boot:spring-boot-starter-test"}test {  useJUnitPlatform()}

創建資源表示類

設置項目和生成系統后,可以創建 Web 服務了。

從考慮服務交互開始該過程。

該服務將使用查詢字符串中的參數(可選)處理對 的請求。請求應返回正文中包含 JSON 的響應,以表示問候語。它應類似于以下列表:??GET????/greeting????name????GET????200 OK??

{    "id": 1,    "content": "Hello, World!"}

該字段是問候語的唯一標識符,是問候語的文本表示形式。??id????content??

若要對問候語表示形式進行建模,請創建資源表示形式類。提供一個普通的舊 Java 對象,其中包含 和 數據的字段、構造函數和訪問器,如以下清單(來自 )所示:??id????content????src/main/java/com/example/restservicecors/Greeting.java??

package com.example.restservicecors;public class Greeting {  private final long id;  private final String content;  public Greeting() {    this.id = -1;    this.content = "";  }  public Greeting(long id, String content) {    this.id = id;    this.content = content;  }  public long getId() {    return id;  }  public String getContent() {    return content;  }}

彈簧使用杰克遜·?庫,用于自動將類型的實例封送到 JSON 中。??Greeting??

創建資源控制器

在Spring構建RESTful Web服務的方法中,HTTP請求由控制器處理。這些組件很容易通過@Controller注釋,以及以下清單 (from ) 中顯示的 通過返回類的新實例來處理請求:??GreetingController????src/main/java/com/example/restservicecors/GreetingController.java????GET????/greeting????Greeting??

package com.example.restservicecors;import java.util.concurrent.atomic.AtomicLong;import org.springframework.web.bind.annotation.CrossOrigin;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class GreetingController {  private static final String template = "Hello, %s!";  private final AtomicLong counter = new AtomicLong();  @CrossOrigin(origins = "http://localhost:8080")  @GetMapping("/greeting")  public Greeting greeting(@RequestParam(required = false, defaultValue = "World") String name) {    System.out.println("==== get greeting ====");    return new Greeting(counter.incrementAndGet(), String.format(template, name));  }}

這個控制器簡潔明了,但引擎蓋下有很多事情要做。我們一步一步地分解它。

注釋可確保將 HTTP 請求映射到該方法。??@RequestMapping????/greeting????greeting()??

前面的示例使用批注,該批注充當 的快捷方式。我們在這種情況下使用是因為它便于測試。Spring 仍將拒絕源與 CORS 配置不匹配的 GET 請求。瀏覽器不需要發送 CORS 預檢請求,但如果我們想觸發預檢,我們可以在正文中使用并接受一些 JSON。??@GetMapping????@RequestMapping(method = RequestMethod.GET)????GET????@PostMapping??

??@RequestParam??將查詢字符串參數的值綁定到方法的參數中。此查詢字符串參數不是 。如果請求中不存在,則使用 of。??name????name????greeting()????required????defaultValue????World??

方法主體的實現創建并返回一個新對象,屬性的值基于 中的下一個值,屬性的值基于查詢參數或默認值。它還通過使用問候語來格式化給定的格式。??Greeting????id????counter????content????name????template??

傳統 MVC 控制器和前面顯示的 RESTful Web 服務控制器之間的主要區別在于創建 HTTP 響應正文的方式。這個 RESTful Web 服務控制器不是依靠視圖技術來執行問候數據到 HTML 的服務器端呈現,而是填充并返回一個對象。對象數據以 JSON 形式直接寫入 HTTP 響應。??Greeting??

為此,{RestController}[] 注解假定每個方法都繼承??@RestController??@ResponseBody默認情況下的語義。因此,返回的對象數據將直接插入到響應正文中。

由于Spring的HTTP消息轉換器支持,該對象自然而然地轉換為JSON。因為??Greeting??杰克遜在類路徑上,春天的MappingJackson2HttpMessageConverter自動選擇將實例轉換為 JSON。??Greeting??

啟用 CORS

您可以從單個控制器或全局啟用跨源資源共享 (CORS)。以下主題介紹了如何執行此操作:

控制器方法 CORS 配置全局 CORS 配置

控制器方法 CORS 配置

為了使 RESTful Web 服務在其響應中包含 CORS 訪問控制標頭,您必須向處理程序方法添加注釋,如以下清單 (from ) 所示:??@CrossOrigin????src/main/java/com/example/restservicecors/GreetingController.java??

@CrossOrigin(origins = "http://localhost:8080")  @GetMapping("/greeting")  public Greeting greeting(@RequestParam(required = false, defaultValue = "World") String name) {    System.out.println("==== get greeting ====");    return new Greeting(counter.incrementAndGet(), String.format(template, name));

此注釋僅為此特定方法啟用跨源資源共享。默認情況下,它允許所有源、所有標頭和注釋中指定的 HTTP 方法。此外,還使用了 30 分鐘。您可以通過指定以下批注屬性之一的值來自定義此行為:??@CrossOrigin????@RequestMapping????maxAge??

??origins????methods????allowedHeaders????exposedHeaders????allowCredentials????maxAge??.

在此示例中,我們只允許發送跨源請求。??http://localhost:8080??

您還可以在控制器類級別添加注釋,以在此類的所有處理程序方法上啟用 CORS。??@CrossOrigin??

全局 CORS 配置

除了(或作為基于注釋的細粒度配置的替代方法)之外,您還可以定義一些全局 CORS 配置。這類似于使用 但可以在 Spring MVC 中聲明并與細粒度配置相結合。默認情況下,允許使用所有源和、 和方法。??Filter????@CrossOrigin????GET????HEAD????POST??

下面的清單(來自)顯示了類中的方法:??src/main/java/com/example/restservicecors/GreetingController.java????greetingWithJavaconfig????GreetingController??

@GetMapping("/greeting-javaconfig")  public Greeting greetingWithJavaconfig(@RequestParam(required = false, defaultValue = "World") String name) {    System.out.println("==== in greeting ====");    return new Greeting(counter.incrementAndGet(), String.format(template, name));

方法和方法之間的區別(用于??greetingWithJavaconfig????greeting??控制器級 CORS 配置?) 是路線(而不是 )和原點的存在。??/greeting-javaconfig????/greeting????@CrossOrigin??

下面的清單(來自)顯示了如何在應用程序類中添加 CORS 映射:??src/main/java/com/example/restservicecors/RestServiceCorsApplication.java??

public WebMvcConfigurer corsConfigurer() {    return new WebMvcConfigurer() {      @Override      public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:8080");      }    };  }

您可以輕松更改任何屬性(如示例中所示),以及將此 CORS 配置應用于特定路徑模式。??allowedOrigins??

您可以組合全局級和控制器級 CORS 配置。

創建應用程序類

Spring Initializr 為您創建了一個基本的應用程序類。以下清單(來自 )顯示了初始類:??initial/src/main/java/com/example/restservicecors/RestServiceCorsApplication.java??

package com.example.restservicecors;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class RestServiceCorsApplication {  public static void main(String[] args) {    SpringApplication.run(RestServiceCorsApplication.class, args);  }}

您需要添加一個方法來配置如何處理跨源資源共享。以下清單(來自 )顯示了如何執行此操作:??complete/src/main/java/com/example/restservicecors/RestServiceCorsApplication.java??

@Bean  public WebMvcConfigurer corsConfigurer() {    return new WebMvcConfigurer() {      @Override      public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:8080");      }    };  }

下面的清單顯示了已完成的應用程序類:

package com.example.restservicecors;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;import org.springframework.web.servlet.config.annotation.CorsRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@SpringBootApplicationpublic class RestServiceCorsApplication {  public static void main(String[] args) {    SpringApplication.run(RestServiceCorsApplication.class, args);  }  @Bean  public WebMvcConfigurer corsConfigurer() {    return new WebMvcConfigurer() {      @Override      public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:8080");      }    };  }}

??@SpringBootApplication??是一個方便的注釋,它添加了以下所有內容:

??@Configuration??:將類標記為應用程序上下文的 Bean 定義源。??@EnableAutoConfiguration??:告訴 Spring 引導根據類路徑設置、其他 bean 和各種屬性設置開始添加 bean。例如,如果 在類路徑上,則此注釋會將應用程序標記為 Web 應用程序并激活關鍵行為,例如設置 .spring-webmvcDispatcherServlet??@ComponentScan??:告訴 Spring 在包中查找其他組件、配置和服務,讓它找到控制器。com/example

該方法使用 Spring Boot 的方法啟動應用程序。您是否注意到沒有一行 XML?也沒有文件。此 Web 應用程序是 100% 純 Java,您無需處理配置任何管道或基礎結構。??main()????SpringApplication.run()????web.xml??

構建可執行的 JAR

您可以使用 Gradle 或 Maven 從命令行運行應用程序。您還可以構建一個包含所有必需依賴項、類和資源的可執行 JAR 文件并運行該文件。通過構建可執行 jar,可以輕松地在整個開發生命周期中跨不同環境等將服務作為應用程序進行交付、版本控制和部署。

如果使用 Gradle,則可以使用 .或者,您可以使用 JAR 文件生成 JAR 文件,然后運行該文件,如下所示:??./gradlew bootRun????./gradlew build??

java -jar build/libs/gs-rest-service-cors-0.1.0.jar

如果使用 Maven,則可以使用 運行應用程序。或者,您可以使用 JAR 文件生成 JAR 文件,然后運行該文件,如下所示:??./mvnw spring-boot:run????./mvnw clean package??

java -jar target/gs-rest-service-cors-0.1.0.jar

此處描述的步驟將創建一個可運行的 JAR。你也可以構建經典 WAR 文件.

將顯示日志記錄輸出。該服務應在幾秒鐘內啟動并運行。

測試服務

現在服務已啟動,請在瀏覽器中訪問,您應該看到:??http://localhost:8080/greeting??

{"id":1,"content":"Hello, World!"}

通過訪問提供查詢字符串參數。屬性的值從 更改為 ,如下面的清單所示:??name????http://localhost:8080/greeting?name=User????content????Hello, World!????Hello User!??

{"id":2,"content":"Hello, User!"}

此更改表明 中的排列按預期工作。參數的默認值為 ,但始終可以通過查詢字符串顯式重寫。??@RequestParam????GreetingController????name????World??

此外,該屬性已從 更改為 。這證明您正在跨多個請求處理同一實例,并且其字段在每次調用時都會按預期遞增。??id????1????2????GreetingController????counter??

現在,您可以測試 CORS 標頭是否已到位,并允許來自其他源的 Javascript 客戶端訪問該服務。為此,您需要創建一個 Javascript 客戶端來使用該服務。以下清單顯示了此類客戶端:

首先,創建一個名為 (from ) 的簡單 Javascript 文件,其中包含以下內容:??hello.js????complete/public/hello.js??

$(document).ready(function() {    $.ajax({        url: "http://localhost:8080/greeting"    }).then(function(data, status, jqxhr) {       $(".greeting-id").append(data.id);       $(".greeting-content").append(data.content);       console.log(jqxhr);    });});

此腳本使用 jQuery 在 使用 REST 服務。它由 加載,如以下清單 (from ) 所示:??http://localhost:8080/greeting????index.html????complete/public/index.html??

            Hello CORS        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>        <script src="hello.js"></script>                

The ID is

The content is

這本質上是創建于使用 jQuery 使用 RESTful Web 服務,稍作修改,以便在 localhost 端口 8080 上運行時使用服務。有關如何開發此客戶端的更多詳細信息,請參閱該指南。

要啟動在本地主機上的端口 8080 上運行的客戶端,請運行以下 Maven 命令:

./mvnw spring-boot:run

如果您使用 Gradle,則可以使用以下命令:

./gradlew bootRun

應用啟動后,打開??http://localhost:8080??在瀏覽器中,您應該看到以下內容:

若要測試 CORS 行為,需要從另一個服務器或端口啟動客戶端。這樣做不僅可以避免兩個應用程序之間的沖突,還可以確保客戶端代碼從與服務不同的源提供。若要啟動在端口 9000 的本地主機上運行的應用(以及已在端口 8080 上運行的應用),請運行以下 Maven 命令:

./mvnw spring-boot:run -Dserver.port=9000

如果您使用 Gradle,則可以使用以下命令:

./gradlew bootRun --args="--server.port=9000"

應用啟動后,打開??http://localhost:9000??在瀏覽器中,您應該看到以下內容:

如果服務響應包含 CORS 標頭,則 ID 和內容將呈現到頁面中。但是,如果 CORS 標頭丟失(或對于客戶端來說不足),則瀏覽器會使請求失敗,并且值不會呈現到 DOM 中。

總結

祝賀!您剛剛開發了一個 RESTful Web 服務,其中包括與 Spring 的跨域資源共享。

標簽: 應用程序 資源共享 您還可以

上一篇:當前速訊:使用基于 SOAP 的 Web 服務的過程
下一篇:Linux 中的 lsof 命令使用大全