使用 Spring RestTemplate 壓縮請求

HTTP Client-Side,REST,Spring
Remote
1
08:40 AM · Dec 01 ,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 Web 服務器添加 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.