编写一个压缩请求体的OkHttp拦截器

时间:2015-07-22 20:18:08

标签: java retrofit java-io okhttp gzipoutputstream

我试图编写一个使用Gzip压缩请求体的拦截器。

我的服务器不支持压缩请求,因此我将使用application/octet-stream 而不是 Content-Type: gzip并手动压缩请求正文,它将被解压缩在后端手动。

public class GzipRequestInterceptor implements Interceptor {

    final String CONTENT_TYPE = "application/octet-stream";

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        if (originalRequest.body() == null || CONTENT_TYPE.equals(originalRequest.header("Content-Type"))) {
            return chain.proceed(originalRequest);
        }

        Request compressedRequest = originalRequest.newBuilder()
                .header("Content-Type", CONTENT_TYPE)
                .method(originalRequest.method(), gzip(originalRequest.body()))
                .build();
        return chain.proceed(compressedRequest);
    }

    private RequestBody gzip(final RequestBody body) throws IOException {

        final Buffer inputBuffer = new Buffer();
        body.writeTo(inputBuffer);

        final Buffer outputBuffer = new Buffer();
        GZIPOutputStream gos = new GZIPOutputStream(outputBuffer.outputStream());

        gos.write(inputBuffer.readByteArray());

        inputBuffer.close();
        gos.close();

        return new RequestBody() {
            @Override
            public MediaType contentType() {
                return body.contentType();
            }

            @Override
            public long contentLength() {
                return outputBuffer.size();
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                ByteString snapshot = outputBuffer.snapshot();
                sink.write(snapshot);
            }
        };
    }
}

它不起作用 - 在触发请求30秒后,收到500 Server Error。在服务器上有一个超时异常。

我的猜测是我在gzip方法输入/输出上做错了......有什么想法吗?

更新如果我停止应用,请求会成功通过,这是否表示应用仍在等待来自outputBuffer的数据?

1 个答案:

答案 0 :(得分:0)

这是您正在寻找的Interceptors,请查看重写请求 - 章节。