Spring Boot Topic
Spring Boot Enable HTTP Compression
HTTP compression is a technique that reduces the size of HTTP responses, resulting in faster page load times, reduced bandwidth usage, and improved user experience. Spring Boot makes it easy to enable and configure HTTP compression.
What is HTTP Compression?
HTTP compression works by:
-
Compressing response bodies before sending them to clients
-
Using algorithms like GZIP or Deflate
-
Reducing file sizes typically by 60-80%
-
Automatically handling compression/decompression via HTTP headers
Enabling HTTP Compression in Spring Boot
1. Basic Configuration
Spring Boot enables HTTP compression through simple configuration properties in application.properties or application.yml:
application.properties:
# Enable HTTP compression
server.compression.enabled=true
# Minimum response size to trigger compression (default: 2048 bytes)
server.compression.min-response-size=1024
# MIME types that should be compressed
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml
# Compression level (0-9, where 0=no compression, 9=maximum compression)
server.compression.level=6
application.yml:
server:
compression:
enabled: true
min-response-size: 1024
mime-types:
- text/html
- text/xml
- text/plain
- text/css
- text/javascript
- application/javascript
- application/json
- application/xml
level: 6
2. Advanced Configuration
For more granular control, you can configure compression programmatically:
@Configuration
public class CompressionConfig {
@Bean
public FilterRegistrationBean<CompressingFilter> compressionFilter() {
FilterRegistrationBean<CompressingFilter> registrationBean =
new FilterRegistrationBean<>();
CompressingFilter compressingFilter = new CompressingFilter();
// Configure compression settings
registrationBean.setFilter(compressingFilter);
registrationBean.addUrlPatterns("/*");
// Set initialization parameters
registrationBean.addInitParameter("compressionThreshold", "1024");
registrationBean.addInitParameter("compressedContentTypes",
"text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json");
return registrationBean;
}
}
How HTTP Compression Works
1. Request-Response Flow
Client Request:
GET /api/data HTTP/1.1
Host: example.com
Accept-Encoding: gzip, deflate ← Client indicates compression support
Server Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip ← Server indicates compressed content
Content-Length: 1500
[Compressed JSON data...]
2. Compression Process
// Simplified internal Spring Boot process
public class CompressionProcess {
public void handleResponse(HttpServletResponse response, byte[] content) {
// Check if compression should be applied
if (shouldCompress(response, content)) {
// Apply GZIP compression
ByteArrayOutputStream compressed = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(compressed)) {
gzip.write(content);
}
byte[] compressedData = compressed.toByteArray();
// Set appropriate headers
response.setHeader("Content-Encoding", "gzip");
response.setContentLength(compressedData.length);
// Write compressed data
response.getOutputStream().write(compressedData);
} else {
// Write uncompressed data
response.getOutputStream().write(content);
}
}
private boolean shouldCompress(HttpServletResponse response, byte[] content) {
return content.length >= minResponseSize &&
isCompressibleContentType(response.getContentType()) &&
clientSupportsCompression(request);
}
}
Configuration Parameters Explained
1. Compression Levels
| Level | Compression | Speed | Use Case |
|---|---|---|---|
| 0 | No compression | Fastest | Development |
| 1 | Minimal | Very Fast | Real-time applications |
| 6 | Balanced | Balanced | General web applications |
| 9 | Maximum | Slowest | Static content delivery |
2. MIME Type Considerations
Highly compressible:
-
Text-based content (HTML, CSS, JS, JSON, XML)
-
Compression ratio: 60-80%
Less compressible:
-
Already compressed formats (JPEG, PNG, PDF, ZIP)
-
Compression ratio: 0-10% (may even increase size)
3. Response Size Threshold
-
Small files: Below threshold may not benefit from compression
-
Large files: Significant bandwidth savings
-
Default: 2048 bytes (optimal balance for most applications)
Custom Compression Configuration
1. Custom Compression Filter
@Component
public class CustomCompressionFilter implements Filter {
private static final String[] COMPRESSIBLE_TYPES = {
"text/html", "text/xml", "text/plain", "text/css",
"text/javascript", "application/javascript", "application/json"
};
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (supportsCompression(httpRequest)) {
CompressedResponseWrapper wrappedResponse =
new CompressedResponseWrapper(httpResponse);
chain.doFilter(request, wrappedResponse);
wrappedResponse.finishResponse();
} else {
chain.doFilter(request, response);
}
}
private boolean supportsCompression(HttpServletRequest request) {
String acceptEncoding = request.getHeader("Accept-Encoding");
return acceptEncoding != null &&
(acceptEncoding.contains("gzip") || acceptEncoding.contains("deflate"));
}
}
2. Response Wrapper for Compression
public class CompressedResponseWrapper extends HttpServletResponseWrapper {
private GZIPServletOutputStream gzipStream;
private PrintWriter writer;
private boolean compressionEnabled = false;
public CompressedResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (writer != null) {
throw new IllegalStateException("getWriter() has already been called");
}
if (gzipStream == null) {
gzipStream = new GZIPServletOutputStream(super.getOutputStream());
compressionEnabled = true;
}
return gzipStream;
}
public void finishResponse() throws IOException {
if (writer != null) {
writer.close();
} else if (gzipStream != null) {
gzipStream.close();
}
}
}
Testing Compression
1. Using curl to Test
# Test without compression
curl -H "Accept-Encoding: identity" http://localhost:8080/api/data
# Test with GZIP compression
curl -H "Accept-Encoding: gzip" --compressed http://localhost:8080/api/data
# Check response headers
curl -I -H "Accept-Encoding: gzip" http://localhost:8080/api/data
2. Unit Testing
@SpringBootTest
class CompressionTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testResponseIsCompressed() {
HttpHeaders headers = new HttpHeaders();
headers.set("Accept-Encoding", "gzip");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(
"/api/data", HttpMethod.GET, entity, String.class);
// Verify compression headers
assertThat(response.getHeaders().getContentEncoding()).isEqualTo("gzip");
}
}
Performance Considerations
1. CPU vs Bandwidth Trade-off
// Performance impact analysis
public class CompressionPerformance {
// Compression reduces bandwidth but increases CPU usage
public void analyzeTradeoff() {
// Small files: Compression overhead may outweigh benefits
// Large files: Significant bandwidth savings
// Text content: High compression ratio
// Binary content: Low compression ratio
}
}
2. Recommended Settings by Use Case
Web Application:
server.compression.enabled=true server.compression.min-response-size=1024 server.compression.level=6
API Service:
server.compression.enabled=true server.compression.min-response-size=512 # API responses are often smaller server.compression.mime-types=application/json server.compression.level=4
Static Content Server:
server.compression.enabled=true server.compression.min-response-size=2048 server.compression.level=9 # Maximum compression for static files
Common Issues and Solutions
1. Compression Not Working
Check:
-
Client sends
Accept-Encodingheader -
Response size exceeds minimum threshold
-
Content type is in compressible types list
-
No other filters interfere with compression
2. Performance Problems
Solutions:
-
Reduce compression level for CPU-intensive applications
-
Increase minimum response size threshold
-
Exclude already-compressed content types
3. Browser Compatibility
Most modern browsers support GZIP and Deflate compression automatically. Ensure your configuration includes:
server.compression.mime-types=text/html,text/css,text/javascript,application/javascript,application/json,application/xml,text/xml,text/plain
Best Practices
-
Enable compression for all production environments
-
Use appropriate compression levels based on your use case
-
Monitor CPU usage if serving high traffic
-
Test with real data to find optimal settings
-
Exclude already compressed formats (images, PDFs, etc.)
-
Consider CDN compression for static assets
HTTP compression in Spring Boot is a powerful feature that significantly improves application performance with minimal configuration effort.
Comments (0)
No comments yet. Be the first to comment!