知識庫 / HTTP Client-Side RSS 訂閱

使用Feign處理帶請求體GET請求

HTTP Client-Side,Spring Cloud
HongKong
6
10:36 AM · Dec 06 ,2025

1. 引言

HTTP 請求通常是 Web 和 API 通信的核心。它們是協議和正確數據交換的基石。

在本教程中,我們將探討如何使用 Spring Cloud OpenFeign 以及請求體來處理 GET 請求。

2. 瞭解問題

根據 HTTP/1.1 規範,GET 請求不應包含請求體:

  • GET 的目的是檢索數據(而不是發送複雜的負載)
  • 大多數服務器和代理忽略或拒絕 GET 請求中的請求體。
  • 緩存層(如 CDN 或瀏覽器)在 GET 請求包含請求體時可能會出現問題。

然而,某些外部 API 或遺留系統仍然期望 GET 請求包含請求體以傳遞複雜的搜索條件。 挑戰在於,Spring Cloud OpenFeign 默認情況下不為 GET 請求序列化請求體——它嚴格遵循 HTTP 標準。 但通過一些調整,可以處理此類場景。

3. 項目設置

要使用 Feign,我們需要將 OpenFeign 依賴添加到 pom.xml 文件中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

接下來,我們需要通過在主應用程序類中使用 @EnableFeignClients</em/> 標註來啓用它:

@SpringBootApplication
@EnableFeignClients
public class FeignDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignDemoApplication.class, args);
    }
}

這樣,我們就可以使用各自的功能。

4. 嘗試帶有請求體(Body)的 GET 請求

讓我們先看看如果我們簡單地嘗試向 Feign 發送帶有 @RequestBody 的 GET 請求會發生什麼。

例如,我們首先定義一個 Feign 客户端:

@FeignClient(name = "sampleClient", url = "http://localhost:8080")
public interface GetBodyFeignClient {

    @GetMapping("/api/search")
    String search(@RequestBody SearchRequest searchRequest);
}

接下來,我們定義請求模型:

public class SearchRequest {
    private String keyword;
    private String category;

    // getters and setters
}

如果我們在測試中嘗試調用此方法,我們可以看到結果:

SearchRequest request = new SearchRequest();
request.setKeyword("spring");
request.setCategory("tutorial");

Assertions.assertThrows(FeignException.MethodNotAllowed.class, () -> {
  getBodyFeignClient.search(request);
});

我們收到一個異常

feign.FeignException$MethodNotAllowed: status 405 reading SampleFeignClient#search(SearchRequest)

這由於在 GET 方法中存在請求體,導致 Feign 底層基礎設施構建數據對象,而服務器並未期望。

默認情況下,Feign 和 Spring MVC 不允許 GET 請求包含請求體,任何嘗試發送請求體的情況都會在發送請求之前被忽略。一些服務器會直接拒絕此類請求,並返回 HTTP 400 或 405 錯誤。

5. 使用 @SpringQueryMap 解決 GET 請求問題

為了解決此問題,正確的方法是使用 @SpringQueryMap 而不是 @RequestBody。 此註解告訴 Feign 將數據對象的字段序列化為 URL 查詢參數,從而確保符合 HTTP GET 語義,並可在跨服務器和代理的環境中實現可靠操作。

因此,我們可以更新 Feign 客户端接口:

@FeignClient(name = "sampleClient", url = "http://localhost:8080")
public interface GetBodyFeignClient {

    @GetMapping("/api/search")
    String searchWithSpringQueryMap(@SpringQueryMap SearchRequest searchRequest);
}

接下來,我們調用相關的設置方法並執行請求:

SearchRequest request = new SearchRequest();
request.setKeyword("spring");
request.setCategory("tutorial");

getBodyFeignClient.searchWithSpringQueryMap(request);

Feign 生成一個 GET 請求,例如如下所示:

GET http://localhost:8080/api/search?keyword=spring&category=tutorial

值得注意的是,SearchRequest對象中的字段會自動轉換為查詢參數,從而消除了需要發送請求體的需求。這種方法避免了我們在使用GET請求時可能出現的405 Method Not Allowed400 Bad Request錯誤

這種集成的方案不僅解決了問題,還確保API調用與標準HTTP緩存、代理行為和服務器期望相兼容,使其更安全、更可預測。

6. 結論

在本文中,我們學習瞭如何使用@SpringQueryMap來處理需要多個參數或複雜搜索標準的 GET 請求,同時完全符合 HTTP 規範。

如往常一樣,源代碼可在 GitHub 上找到:https://github.com/eugenp/tutorials/tree/master/spring-cloud-modules/spring-cloud-openfeign-2

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

發佈 評論

Some HTML is okay.