【问题标题】:Handle gzip response with retrofit通过改造处理 gzip 响应
【发布时间】:2014-04-18 23:33:41
【问题描述】:

我用retrofit 调用一个简单的GET 来:

https://api.stackexchange.com/2.2/sites

我收到以下回复:

---> HTTP GET https://api.stackexchange.com/2.2/sites
---> END HTTP (0-byte body)
<--- HTTP 200 https://api.stackexchange.com/2.2/sites (1182ms)
: HTTP/1.1 200 OK
Date: Thu, 13 Mar 2014 22:01:03 GMT
Access-Control-Allow-Origin: *
Content-Length: 3073
Content-Encoding: gzip
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Credentials: false
Content-Type: application/json; charset=utf-8
Cache-Control: private

�O �-MB���-�'4��ѽ>K� ��0k��$��ϴ�;|Vۥ�\�Lsd�m�0�Z�=�� �|����6�eD�pw��^z+�ZW7���u��" ��J�?z��#��w�CV���{��p��]��.��?��>j��\�+j�}�IL-�w."A�=��� ��M�}�D1��x����å$!�O*���P�)����\�8�0y��D{�8�n�7���}�kb�[

一切正常,StackExchange 返回压缩后的 JSON。但是retrofit 好像不支持。我得到以下异常:

retrofit.RetrofitError: retrofit.converter.ConversionException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
    at retrofit.RetrofitError.conversionError(RetrofitError.java:32)
    at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:408)
    at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:282)
    at com.sun.proxy.$Proxy5.listSites(Unknown Source)
    at mobi.hsz.project.ProjectTest.listSites(ProjectTest.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runners.Suite.runChild(Suite.java:127)
    at org.junit.runners.Suite.runChild(Suite.java:26)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: retrofit.converter.ConversionException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
    at retrofit.converter.GsonConverter.fromBody(GsonConverter.java:67)
    at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:393)
    ... 38 more
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
    at com.google.gson.Gson.fromJson(Gson.java:803)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at retrofit.converter.GsonConverter.fromBody(GsonConverter.java:63)
    ... 39 more
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165)
    ... 42 more

如何处理gzip 内容类型?

【问题讨论】:

标签: java json gzip retrofit


【解决方案1】:

解决方案是向OkHttp 添加一个依赖项。没有别的了。

<dependency>
    <groupId>com.squareup.okhttp</groupId>
    <artifactId>okhttp</artifactId>
    <version>1.5.1</version>
</dependency>

【讨论】:

  • Retrofit 下的底层 HTTP 客户端应该在将内容返回之前自动解压缩内容。 OkHttp 就是这样做的。
  • @JakeWharton 我尝试在没有OkHttp 的情况下手动设置Content-TypeRequestInterceptorHeaders 注释)但没有运气。只有添加这个依赖项(没有额外的方法)才能工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
  • 2015-12-14
  • 1970-01-01
  • 2020-09-15
  • 1970-01-01
  • 2020-06-17
  • 1970-01-01
相关资源
最近更新 更多