Spring REST API 定製媒體類型

REST,Spring
Remote
1
01:24 PM · Dec 01 ,2025

1. 概述

在本教程中,我們將探討如何定義自定義媒體類型並使用 Spring REST 控制器生成它們。

使用自定義媒體類型的一個良好用例是版本 API。

2. API – Version 1

我們先來看一個簡單的例子——一個 API,通過 ID 暴露一個單一的資源。

我們將從資源暴露給客户端的 Version 1 開始。為了做到這一點,我們將使用自定義 HTTP 標頭——“application/vnd.baeldung.api.v1+json”

客户端將通過 Accept 標頭請求此自定義媒體類型。

以下是我們的簡單端點:

@RequestMapping(
  method = RequestMethod.GET, 
  value = "/public/api/items/{id}", 
  produces = "application/vnd.baeldung.api.v1+json"
)
@ResponseBody
public BaeldungItem getItem( @PathVariable("id") String id ) {
    return new BaeldungItem("itemId1");
}

請注意 produces參數此處——指定此 API 可以處理的自定義媒體類型。

現在,BaeldungItem資源——具有單個字段itemId:

public class BaeldungItem {
    private String itemId;
    
    // standard getters and setters
}

最後,我們為端點編寫一個集成測試:

@Test
public void givenServiceEndpoint_whenGetRequestFirstAPIVersion_then200() {
    given()
      .accept("application/vnd.baeldung.api.v1+json")
    .when()
      .get(URL_PREFIX + "/public/api/items/1")
    .then()
      .contentType(ContentType.JSON).and().statusCode(200);
}

3. API – Version 2

現在假設我們需要更改我們向客户端暴露的詳細信息,使用我們的 Resource。

我們以前暴露了一個原始 ID – 現在我們需要隱藏它並暴露一個名稱,以獲得更大的靈活性。

重要的是要理解,這種更改與舊版本不兼容,本質上是一個破壞性更改。

這是我們的新 Resource 定義:

public class BaeldungItemV2 {
    private String itemName;

    // standard getters and setters
}

因此,我們需要做的就是 – 將我們的 API 遷移到第二個版本。

我們將通過 創建我們自定義媒體類型的下個版本以及定義新的端點來實現這個目標:

@RequestMapping(
  method = RequestMethod.GET, 
  value = "/public/api/items/{id}", 
  produces = "application/vnd.baeldung.api.v2+json"
)
@ResponseBody
public BaeldungItemV2 getItemSecondAPIVersion(@PathVariable("id") String id) {
    return new BaeldungItemV2("itemName");
}

因此,我們現在擁有相同的端點,但能夠處理新的 V2 操作。

當客户端請求 “application/vnd.baeldung.api.v1+json” 時,Spring 將委託給舊操作,客户端將收到一個 BaeldungItem,其中包含 itemId 字段 (V1)。

但是,當客户端現在將 Accept 標頭設置為 “application/vnd.baeldung.api.v2+json” 時,他們將正確地命中新的操作並獲得帶有 itemName 字段 (V2) 的 Resource:

@Test
public void givenServiceEndpoint_whenGetRequestSecondAPIVersion_then200() {
    given()
      .accept("application/vnd.baeldung.api.v2+json")
    .when()
      .get(URL_PREFIX + "/public/api/items/2")
    .then()
      .contentType(ContentType.JSON).and().statusCode(200);
}

請注意,測試與使用不同的 Accept 標頭相似。

4. 在類級別定義自定義媒體類型

最後,我們來談談在類級別定義媒體類型的概念——這同樣可行:

@RestController
@RequestMapping(
  value = "/", 
  produces = "application/vnd.baeldung.api.v1+json"
)
public class CustomMediaTypeController

正如預期的那樣,@RequestMapping 註解可以輕鬆在類級別工作,並允許我們指定 valueproducesconsumes 參數。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.