知識庫 / HTTP Client-Side RSS 訂閱

使用 Spring RestTemplate 壓縮請求方法詳解

HTTP Client-Side,REST,Spring
HongKong
6
03:50 AM · Dec 06 ,2025

1. 引言

在本簡短教程中,我們將探討如何發送包含壓縮數據的 HTTP 請求。

此外,我們還將研究如何配置 Spring Web 應用程序,使其處理壓縮請求。

2. 發送壓縮請求

首先,我們創建一個用於壓縮字節數組的方法。 這在稍後會派上用場。

public static byte[] compress(byte[] body) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {
        gzipOutputStream.write(body);
    }
    return baos.toByteArray();
}

接下來,我們需要實現一個 ClientHttpRequestInterceptor 以修改請求。請注意,我們將同時發送適當的 HTTP 壓縮頭,並調用我們的體裁壓縮方法:

public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec)
  throws IOException {
    HttpHeaders httpHeaders = req.getHeaders();
    httpHeaders.add(HttpHeaders.CONTENT_ENCODING, "gzip");
    httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
    return exec.execute(req, compress(body));
}

我們的攔截器接收外發請求體並使用 GZIP 格式進行壓縮。 在本示例中,我們使用 Java 的標準 GZIPOutputStream 來完成這項工作。

此外,我們必須添加適當的標頭以進行數據編碼。 這讓目標端點知道它正在處理 GZIP 壓縮數據。

最後,我們將攔截器添加到我們的 RestTemplate 定義中:

@Bean
public RestTemplate getRestTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor());
    return restTemplate;
}

3. 處理壓縮請求

默認情況下,大多數 Web 服務器不理解包含壓縮數據的請求。Spring Web 應用程序也不例外。因此,我們需要配置它們來處理此類請求。

目前,僅 Jetty 和 Undertow Web 服務器能夠處理包含 GZIP 格式數據的請求主體。請參閲我們的 Spring Boot 應用程序配置文章,以設置 Jetty 或 Undertow Web 服務器。

3.1. Jetty Web 服務器

在本示例中,我們通過添加 Jetty 的 GzipHandler 來自定義 Jetty Web 服務器。該 Jetty 處理程序旨在壓縮響應並解壓縮請求。

但是,僅僅添加它到 Jetty Web 服務器是不夠的。我們需要將 inflateBufferSize 設置為一個大於零的值,才能啓用解壓縮功能:

@Bean
public JettyServletWebServerFactory jettyServletWebServerFactory() {
    JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
    factory.addServerCustomizers(server -> {
        GzipHandler gzipHandler = new GzipHandler();
        gzipHandler.setInflateBufferSize(1);
        gzipHandler.setHandler(server.getHandler());

        HandlerCollection handlerCollection = new HandlerCollection(gzipHandler);
        server.setHandler(handlerCollection);
    });
    return factory;
}

3.2. Undertow Web 服務器

同樣,我們可以自定義 Undertow Web 服務器以自動解壓縮請求。在這種情況下,我們需要添加一個自定義的 RequestEncodingHandler

我們配置編碼處理程序以處理來自請求的 GZIP 壓縮數據:

@Bean
public UndertowServletWebServerFactory undertowServletWebServerFactory() {
    UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
    factory.addDeploymentInfoCustomizers((deploymentInfo) -> {
        deploymentInfo.addInitialHandlerChainWrapper(handler -> new RequestEncodingHandler(handler)
          .addEncoding("gzip", GzipStreamSourceConduit.WRAPPER));
    });
    return factory;
}

4. 結論

這就是讓壓縮請求工作所需要做的全部!

在本教程中,我們學習瞭如何為 RestTemplate 創建攔截器,以壓縮請求內容。我們還研究瞭如何在 Spring Web 應用程序中自動解壓縮這些請求。

重要的是要注意,我們應該僅將壓縮內容發送到能夠處理此類請求的 Web 服務器。

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

發佈 評論

Some HTML is okay.