栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何使用Spring RestTemplate压缩HTTP请求?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何使用Spring RestTemplate压缩HTTP请求?

我提出了两种解决方案,一种更简单,无需流传输,另一种支持流传输。

如果您 不需要流式传输 ,请使用custom

ClientHttpRequestInterceptor
,一个Spring功能。

RestTemplate rt = new RestTemplate();rt.setInterceptors(Collections.singletonList(interceptor));

interceptor
可能在哪里:

ClientHttpRequestInterceptor interceptor = new ClientHttpRequestInterceptor() {    @Override    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {        request.getHeaders().add("Content-Encoding", "gzip");        byte[] gzipped = getGzip(body);        return execution.execute(request, gzipped);    }  }

getGzip
我复制了

    private byte[] getGzip(byte[] body) throws IOException {        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();        try { GZIPOutputStream zipStream = new GZIPOutputStream(byteStream); try {     zipStream.write(body); } finally {     zipStream.close(); }        } finally { byteStream.close();        }        byte[] compressedData = byteStream.toByteArray();        return compressedData;    }

配置拦截器后,所有请求将被压缩。

这种方法的缺点是它不支持流式传输,因为

ClientHttpRequestInterceptor
将内容作为
byte[]

如果您 需要流式传输,请 创建一个custom

ClientHttpRequestFactory
,说出来
GZipClientHttpRequestFactory
,然后像这样使用它:

    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();    requestFactory.setBufferRequestBody(false);    ClientHttpRequestFactory gzipRequestFactory = new GZipClientHttpRequestFactory(requestFactory);    RestTemplate rt = new RestTemplate(gzipRequestFactory);

哪里

GZipClientHttpRequestFactory
是:

public class GZipClientHttpRequestFactory extends AbstractClientHttpRequestFactoryWrapper {    public GZipClientHttpRequestFactory(ClientHttpRequestFactory requestFactory) {        super(requestFactory);    }    @Override    protected ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod, ClientHttpRequestFactory requestFactory) throws IOException {        ClientHttpRequest delegate = requestFactory.createRequest(uri, httpMethod);        return new ZippedClientHttpRequest(delegate);    }}

并且

ZippedClientHttpRequest
是:

public class ZippedClientHttpRequest extends WrapperClientHttpRequest{    private GZIPOutputStream zip;    public ZippedClientHttpRequest(ClientHttpRequest delegate) {        super(delegate);        delegate.getHeaders().add("Content-Encoding", "gzip");        // here or in getBody could add content-length to avoid chunking        // but is it available ?         // delegate.getHeaders().add("Content-Length", "39");    }    @Override    public OutputStream getBody() throws IOException {        final OutputStream body = super.getBody();        zip = new GZIPOutputStream(body);        return zip;    }    @Override    public ClientHttpResponse execute() throws IOException {        if (zip!=null) zip.close();        return super.execute();    }}

最后

WrapperClientHttpRequest
是:

public class WrapperClientHttpRequest implements ClientHttpRequest {    private final ClientHttpRequest delegate;    protected WrapperClientHttpRequest(ClientHttpRequest delegate) {        super();        if (delegate==null) throw new IllegalArgumentException("null delegate");        this.delegate = delegate;    }    protected final ClientHttpRequest getDelegate() {        return delegate;    }    @Override    public OutputStream getBody() throws IOException {        return delegate.getBody();    }    @Override    public HttpHeaders getHeaders() {        return delegate.getHeaders();    }    @Override    public URI getURI() {        return delegate.getURI();    }    @Override    public HttpMethod getMethod() {        return delegate.getMethod();    }    @Override    public ClientHttpResponse execute() throws IOException {        return delegate.execute();    }}

这种方法使用分块传输编码创建请求,如果知道大小,则可以设置内容长度标头来更改此请求。

ClientHttpRequestInterceptor
和/或自定义
ClientHttpRequestFactory
方法的优点是它可以与RestTemplate的任何方法一起使用。另一种方法,传递一个RequestCallback能够仅与
execute
方法,这是因为RestTemplate的其它方法在内部创建他们自己的RequestCallback(S)产生的内容。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/508754.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号