改造和OkHttp gzip解码

Sim*_*tel 24 java retrofit okhttp

我希望将REST服务作为gzip编码的JSON使用.它提供了Content-Encoding: gzip,但我的OkHttp不会将其编码为可读文本,因此JSON转换器会抛出异常.

---> HTTP GET https://rapla.dhbw-karlsruhe.de/rapla/events?resources=%5B%27rc85dbd6-7d98-4eb7-a7f6-b867213c73d8%27%5D&start=2015-09-01&end=2015-12-31
Accept-Encoding: gzip, deflate
Accept: application/json
Authorization: *not posted*
Content-Type: application/json;charset=utf-8
---> END HTTP (no body)
<--- HTTP 200 https://rapla.dhbw-karlsruhe.de/rapla/events?resources=%5B%27rc85dbd6-7d98-4eb7-a7f6-b867213c73d8%27%5D&start=2015-09-01&end=2015-12-31 (13ms)
Date: Tue, 24 Nov 2015 09:09:10 GMT
Server: Jetty(9.2.2.v20140723)
Expires: Tue, 01 Jan 1980 00:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment
Content-Length: 9684
Via: 1.1 rapla.dhbw-karlsruhe.de
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1448356149978
OkHttp-Received-Millis: 1448356149991

????WK?{??J?`k?_??Z????E?p?>3m?WMa?????p?0??<??
... skipped rest of the body
E??>???S???n 
<--- END HTTP (9684-byte body)
Run Code Online (Sandbox Code Playgroud)

根据Jake Whartons的评论, Content-Encoding: gzipHeader应该告诉OkHttp解码身体.

创建RestAdapter的代码是:

final RestAdapter adapter = new RestAdapter.Builder()
    .setEndpoint(baseUrl)
    .setClient(new OkClient(new OkHttpClient()))
    .setConverter(new GsonConverter(gson))
    .setLogLevel(RestAdapter.LogLevel.FULL)
    .build();
service = adapter.create(RaplaService.class);
Run Code Online (Sandbox Code Playgroud)

gradle依赖项是:

compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.6.0'
Run Code Online (Sandbox Code Playgroud)

我的ServiceInterface中的方法:

@Headers({
        "Accept-Encoding: gzip, deflate",
        "Content-Type: application/json;charset=utf-8",
        "Accept: application/json"
})
@GET("/events")
List<Event> getEvents(@Header("Authorization") String token, @Query("resources") String resources, @Query("start") String start, @Query("end") String end);
Run Code Online (Sandbox Code Playgroud)

Jes*_*son 47

替换这个:

@Headers({
    "Accept-Encoding: gzip, deflate",
    "Content-Type: application/json;charset=utf-8",
    "Accept: application/json"
})
Run Code Online (Sandbox Code Playgroud)

有了这个:

@Headers({
    "Content-Type: application/json;charset=utf-8",
    "Accept: application/json"
})
Run Code Online (Sandbox Code Playgroud)

当您提供自己的Accept-Encoding标题时,您正在指示OkHttp您想要进行自己的解压缩.通过省略它,OkHttp将负责添加标题和解压缩.

  • 是.如果省略Accept-Encoding标头,OkHttp将自动添加自己的并代表您解压缩. (3认同)
  • 如果要禁用OkHttp的自动gzip功能,只需添加Accept-Encoding标头. (3认同)
  • 但如果我省略了"Accept-Encoding:gzip,deflate",那么我会得到压缩响应吗? (2认同)
  • 我刚刚在Retrofit 2上遇到了类似的问题.但在我的情况下,我将`.header("Accept-Encoding","gzip,deflate")添加到请求构建器中. (2认同)
  • @DavidCheung 我不必添加这个。根据 Jesse Wilson 的说法,OkHttp 似乎会自动添加此标头,如果服务器返回 gzip 数据流,它就会足够聪明地知道这一点并对其进行解压缩。如果服务器不响应标头中的 gzip 请求,则不会尝试解压缩它。聪明的。 (2认同)