知識庫 / HTTP Client-Side RSS 訂閱

使用 Spring RestTemplate 攔截器

HTTP Client-Side,Spring Web
HongKong
10
02:02 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將學習如何實現 Spring RestTemplate 攔截器。

我們將通過一個示例,創建一個攔截器,該攔截器會將自定義標頭添加到響應中。

2. Interceptor 使用場景

除了請求頭修改之外,RestTemplate 攔截器在以下場景中也很有用:

  • 請求和響應日誌記錄
  • 使用可配置的退避策略重試請求
  • 基於某些請求參數拒絕請求
  • 修改請求 URL 地址

3. 創建攔截器在大多數編程範式中,攔截器是使程序員能夠通過攔截執行的關鍵組成部分。 Spring 框架也支持各種目的的攔截器。

Spring RestTemplate 允許我們添加實現 ClientHttpRequestInterceptorClientHttpRequestInterceptor 接口,該接口的 intercept(HttpRequest, byte[], ClientHttpRequestExecution)方法將攔截給定的請求並返回響應,從而提供對requestbodyexecution對象訪問權限。

我們將使用ClientHttpRequestExecution參數來執行實際操作,並將請求傳遞到後續的執行鏈。

作為第一步,讓我們創建一個實現ClientHttpRequestInterceptor接口的攔截器類:

public class RestTemplateHeaderModifierInterceptor
  implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(
      HttpRequest request, 
      byte[] body, 
      ClientHttpRequestExecution execution) throws IOException {
 
        ClientHttpResponse response = execution.execute(request, body);
        response.getHeaders().add("Foo", "bar");
        return response;
    }
}

攔截器將在每個發出的請求上被調用,並且它會將自定義標頭 Foo 添加到每個響應中,在執行完成後並返回時。

由於 intercept() 方法包含了 request body 作為參數,因此還可以根據某些條件對請求進行修改,甚至拒絕請求執行。

4. 設置 RestTemplate

現在我們已經創建了攔截器,接下來我們創建 RestTemplate Bean 並將其與我們的攔截器關聯起來:

@Configuration
public class RestClientConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();

        List<ClientHttpRequestInterceptor> interceptors
          = restTemplate.getInterceptors();
        if (CollectionUtils.isEmpty(interceptors)) {
            interceptors = new ArrayList<>();
        }
        interceptors.add(new RestTemplateHeaderModifierInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }
}

在某些情況下,RestTemplate 對象可能已經添加了攔截器。為了確保一切按預期工作,我們的代碼只會初始化攔截器列表,如果它為空時。

正如我們的代碼所示,我們使用默認構造函數創建 RestTemplate 對象,但在某些情況下,我們需要兩次讀取請求/響應流。

例如,如果我們希望攔截器作為請求/響應日誌記錄器使用,則需要兩次讀取它——第一次由攔截器讀取,第二次由客户端讀取。

默認實現允許我們僅一次讀取響應流。為了滿足此類特定場景,Spring 提供了名為 BufferingClientHttpRequestFactory 的特殊類。正如其名稱所示,此類將在 JVM 內存中對請求/響應進行緩衝,以便多次使用。

以下是如何使用 BufferingClientHttpRequestFactory 初始化 RestTemplate 對象,以啓用請求/響應流緩存:

RestTemplate restTemplate 
  = new RestTemplate(
    new BufferingClientHttpRequestFactory(
      new SimpleClientHttpRequestFactory()
    )
  );

5. 測試我們的示例

以下是用於測試我們 RestTemplate 攔截器的 JUnit 測試用例:

public class RestTemplateItegrationTest {
    
    @Autowired
    RestTemplate restTemplate;

    @Test
    public void givenRestTemplate_whenRequested_thenLogAndModifyResponse() {
        LoginForm loginForm = new LoginForm("username", "password");
        HttpEntity<LoginForm> requestEntity
          = new HttpEntity<LoginForm>(loginForm);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        ResponseEntity<String> responseEntity
          = restTemplate.postForEntity(
            "http://httpbin.org/post", requestEntity, String.class
          );
        
        Assertions.assertEquals(responseEntity.getStatusCode(), HttpStatus.OK);
        Assertions.assertEquals(responseEntity.getHeaders()
                .get("Foo")
                .get(0), "bar");
    }
}

在此,我們使用了免費託管的 HTTP 請求和響應服務 http://httpbin.org 來發布我們的數據。 此測試服務將返回我們的請求主體以及一些元數據。

6. 結論本教程主要講解如何設置攔截器並將其添加到 RestTemplate 對象中。 這種攔截器也可用於過濾、監控和控制發出的請求。

RestTemplate 攔截器的一個常見應用場景是添加請求頭,我們在本文中對此進行了詳細説明。

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

發佈 評論

Some HTML is okay.