You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中通过Feign Client Builder非声明式方式实现Gzip压缩

Absolutely! You can absolutely implement Gzip compression for Feign requests using the Feign Client Builder—both via a custom Request Interceptor or a wrapped Encoder work perfectly for this non-declarative approach. Let me walk you through both methods step by step:

1. Using a Custom Request Interceptor

This approach is straightforward: you’ll create an interceptor that modifies the request body (compresses it) and adds the required Content-Encoding header. It works regardless of the underlying encoder you’re using.

First, define the interceptor class:

import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

public class GzipRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // Only compress if there's a non-empty request body
        if (template.requestBody() != null && template.requestBody().length() > 0) {
            try {
                byte[] compressedBody = compress(template.requestBody().asBytes());
                template.body(compressedBody);
                template.header("Content-Encoding", "gzip");
                template.header("Content-Length", String.valueOf(compressedBody.length));
            } catch (IOException e) {
                throw new RuntimeException("Failed to compress request body", e);
            }
        }
    }

    private byte[] compress(byte[] data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (GZIPOutputStream gzipOut = new GZIPOutputStream(baos)) {
            gzipOut.write(data);
        }
        return baos.toByteArray();
    }
}

Then attach it to your Feign Builder:

YourFeignClient client = Feign.builder()
        .requestInterceptor(new GzipRequestInterceptor())
        // Add other required configs (decoder, logger, etc.)
        .target(YourFeignClient.class, "https://your-target-api.com");
2. Using a Wrapped Encoder

If you prefer to tie compression directly to the encoding step (e.g., after converting a Java object to JSON), you can wrap your existing encoder with a custom Gzip-enabled one.

Here’s the wrapped encoder implementation:

import feign.RequestTemplate;
import feign.codec.Encoder;
import feign.codec.EncodeException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.zip.GZIPOutputStream;

public class GzipEncoder implements Encoder {

    private final Encoder delegateEncoder;

    // Wrap your existing encoder (e.g., JacksonEncoder for JSON)
    public GzipEncoder(Encoder delegateEncoder) {
        this.delegateEncoder = delegateEncoder;
    }

    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
        // Let the delegate encoder handle converting the object to raw bytes first
        delegateEncoder.encode(object, bodyType, template);
        
        // Compress the resulting body if it's non-empty
        if (template.requestBody() != null && template.requestBody().length() > 0) {
            try {
                byte[] compressedBody = compress(template.requestBody().asBytes());
                template.body(compressedBody);
                template.header("Content-Encoding", "gzip");
                template.header("Content-Length", String.valueOf(compressedBody.length));
            } catch (IOException e) {
                throw new EncodeException("Failed to compress request body", e);
            }
        }
    }

    private byte[] compress(byte[] data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (GZIPOutputStream gzipOut = new GZIPOutputStream(baos)) {
            gzipOut.write(data);
        }
        return baos.toByteArray();
    }
}

Use it in your Feign Builder by wrapping your base encoder:

// Example using JacksonEncoder for JSON serialization
Encoder baseEncoder = new JacksonEncoder();
YourFeignClient client = Feign.builder()
        .encoder(new GzipEncoder(baseEncoder))
        // Add other configs as needed
        .target(YourFeignClient.class, "https://your-target-api.com");
Key Notes to Keep in Mind
  • Server Compatibility: Ensure the target API supports Gzip-compressed requests (it needs to recognize the Content-Encoding: gzip header and decompress the body correctly).
  • Compression Threshold: Add a check to only compress bodies larger than a certain size (e.g., 1KB)—small payloads often get bigger after compression.
  • Response Decompression: If the server returns Gzipped responses, don’t forget to add a decoder that handles Content-Encoding: gzip (you can use a similar wrapping approach for the Decoder interface).

内容的提问来源于stack exchange,提问作者vignesh muralidharan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:07:33