带有GzipRequestInterceptor的OkHttp导致来自Jetty服务器的{400}错误请求

时间:2015-07-20 07:12:26

标签: java android jetty retrofit okhttp

我的Android应用使用com.squareup.retrofit:retrofit:1.9.0 com.squareup.okhttp:okhttp:2.4.0作为客户端。

更新服务器Jetty 9.3.0.v20150612正在Java 1.8.0_45-b1上运行。我用另一个应用程序测试了相同的服务器,压缩请求已成功发送。

API有一个带@Body Map<String, Object> payload的命令,自动转换为JSON。 在发送未压缩的时效果很好,但它是一个92k的JSON主体,因此最好进行压缩。

我按照说明here创建了一个GzipRequestInterceptor,修复了内容长度,根据指示here添加缓冲区并将其安装到RestAdapter -

OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new GzipRequestInterceptor());

// Create a very simple REST adapter which points the GitAPI endpoint.
RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(BuildConfig.MBE_SERVER_HOST)
        .setClient(new OkClient(client))
        .build();

出于某种原因,它现在抛出错误请求错误 -

retrofit.RetrofitError: 400 Bad Request
        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:388)
        at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
        at java.lang.reflect.Proxy.invoke(Proxy.java:397)
        at $Proxy1.report(Unknown Source)
        at mypackage.ReportRequest.loadDataFromNetwork(ReportRequest.java:40)
        at mypackage.Request$1.doInBackground(Request.java:36)
        at mypackage.Request$1.doInBackground(Request.java:32)
        at android.os.AsyncTask$2.call(AsyncTask.java:288)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)

这是拦截器 -

public class GzipRequestInterceptor implements Interceptor {

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

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

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

            @Override
            public long contentLength() {
                return -1; // We don't know the compressed length in advance!
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
                body.writeTo(gzipSink);
                gzipSink.close();
            }
        };
    }

    private RequestBody requestBodyWithContentLength(final RequestBody body) throws IOException {

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

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

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

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

怎么了?

更新 - 服务器配置

不确定它有多相关,因为它启用了对响应的压缩,这里是启用了GzipFilter的web.xml -

<filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
    <init-param>
        <param-name>mimeTypes</param-name>
        <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,image/svg+xml,application/json</param-value>
    </init-param>
    <init-param>
        <param-name>minGzipSize</param-name>
        <param-value>500</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

etc / jetty-gzip.xml -

<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <Get id="next" name="handler" />
  <Set name="handler">
    <New id="GzipHandler" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
      <Set name="handler"><Ref refid="next" /></Set>
      <Set name="minGzipSize"><Property name="jetty.gzip.minGzipSize" deprecated="gzip.minGzipSize" default="2048"/></Set>
      <Set name="checkGzExists"><Property name="jetty.gzip.checkGzExists" deprecated="gzip.checkGzExists" default="false"/></Set>
      <Set name="compressionLevel"><Property name="jetty.gzip.compressionLevel" deprecated="gzip.compressionLevel" default="-1"/></Set>
      <Set name="excludedAgentPatterns">
        <Array type="String">
          <Item><Property name="jetty.gzip.excludedUserAgent" deprecated="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/></Item>
        </Array>
      </Set>

      <Set name="includedMethods">
        <Array type="String">
          <Item>GET</Item>
          <Item>POST</Item>
        </Array>
      </Set>

    </New>
  </Set>
</Configure>

1 个答案:

答案 0 :(得分:1)

您的网络服务器不支持压缩请求。