1. Introduction
1.介绍
In this short tutorial, we’ll look at how to send HTTP requests containing compressed data.
在这个简短的教程中,我们将看看如何发送包含压缩数据的HTTP请求。
In addition, we’ll look at how to configure a Spring web application so it handles compressed requests.
此外,我们将研究如何配置Spring网络应用程序,使其能够处理压缩的请求。
2. Sending Compressed Requests
2.发送压缩的请求
Firstly, let’s create a method that compresses a byte array. This will come in handy shortly:
首先,让我们创建一个方法来压缩一个字节数组。这个方法很快就会派上用场。
public static byte[] compress(byte[] body) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {
gzipOutputStream.write(body);
}
return baos.toByteArray();
}
Next, we need to implement a ClientHttpRequestInterceptor to modify the request. Note that we’ll both send the appropriate HTTP compression headers as well as call our body-compressing method:
接下来,我们需要实现一个ClientHttpRequestInterceptor来修改该请求。请注意,我们既要发送适当的HTTP压缩头信息,也要调用我们的body压缩方法。
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));
}
Our interceptor takes the outbound request body and compresses it using the GZIP format. In this example, we use Java’s standard GZIPOutputStream to do the work for us.
我们的拦截器接收出站的请求体,并使用GZIP格式对其进行压缩。在这个例子中,我们使用Java的标准GZIPOutputStream来为我们做这个工作。
In addition, we must add the appropriate headers for data encoding. This lets the destination endpoint know it is dealing with GZIP-compressed data.
此外,我们必须为数据编码添加适当的头文件。这让目标端点知道它正在处理GZIP压缩的数据。
Finally, we add the interceptor to our RestTemplate definition:
最后,我们将拦截器添加到我们的RestTemplate定义中。
@Bean
public RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor());
return restTemplate;
}
3. Handling Compressed Requests
3.处理压缩的请求
By default, most web servers do not understand requests containing compressed data. Spring web applications are no different. Therefore, we need to configure them to handle such requests.
默认情况下,大多数Web服务器不理解包含压缩数据的请求。Spring Web应用程序也不例外。因此,我们需要对它们进行配置以处理此类请求。
Currently, only the Jetty and Undertow web servers handle request bodies with data in GZIP format. Please see our article on Spring Boot Application Configuration to set up a Jetty or Undertow web server.
目前,只有Jetty和Undertow Web服务器可以处理带有GZIP格式数据的请求体。请参阅我们关于Spring Boot 应用程序配置的文章,以设置 Jetty 或 Undertow Web 服务器。
3.1. Jetty Web Server
3.1 Jetty网络服务器
In this example, we customize a Jetty web server by adding a Jetty GzipHandler. This Jetty handler is built to compress responses and decompress requests.
在这个例子中,我们通过添加一个Jetty GzipHandler来定制一个Jetty网络服务器。这个Jetty处理程序是用来压缩响应和解压请求的。
However, adding it the Jetty web server is not enough. We need to set the inflateBufferSize to a value greater than zero to enable decompression:
然而,在Jetty网络服务器上添加它是不够的。我们需要将inflateBufferSize设置为大于0的值,以实现解压。
@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 Server
3.2 Undertow网络服务器
Likewise, we can customize an Undertow web server to automatically decompress requests for us. In this case, we need to add a custom RequestEncodingHandler.
同样地,我们可以定制一个Undertow网络服务器,让它自动为我们解压请求。在这种情况下,我们需要添加一个自定义的RequestEncodingHandler。
We configure the encoding handler to process GZIP source data from the request:
我们配置编码处理程序来处理来自请求的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. Conclusion
4.结论
And that’s all we need to do to get compressed requests working!
这就是我们需要做的所有事情,以使压缩请求发挥作用!”。
In this tutorial, we covered how to create an interceptor for a RestTemplate that compresses the content of a request. Also, we looked at how to automatically decompress these requests in our Spring web applications.
在本教程中,我们介绍了如何为RestTemplate创建一个拦截器,压缩请求的内容。此外,我们还研究了如何在我们的Spring Web应用程序中自动解压这些请求。
It’s important to note that we should only send compressed content to web servers capable of handling such requests.
值得注意的是,我们应该只向能够处理这种请求的网络服务器发送压缩内容。
A complete working example for the Jetty web server is over on GitHub.
一个完整的Jetty网络服务器的工作实例在GitHub上。