java - GSON 应为 BEGIN_ARRAY 但在第 1 行错误为 STRING

标签 java android gson retrofit2

我正在尝试使用从 API 返回的 Retrofit 和 GSON 解析字符串数组:

这是响应通常的样子(案例 1):

["Scan finished, scan information embedded in this object", "https://www.virustotal.com/url/297c349554bdc7e2f09a85be309f08cb2f16a9174068bd5bc6e298ed90a5eed9/analysis/1485313628/", 8, 64]

这是特定情况下的响应(案例 2):

["Scan request successfully queued, come back later for the report", "https://www.virustotal.com/url/d06ed0b4b29aab735ee7b85c5c0af98fd4d983edcc597afe60e4c4ac2e25ea08/analysis/1485847248/", null, null]

在这种情况下(案例 2),我收到来自 Retrofit/GSON 的错误:

W/System.err: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 2 path $
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:117)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:106)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at java.lang.Thread.run(Thread.java:761)

我这样调用 API:

Call<ArrayList<String>> scanResults = myAPI.getScanResults(id);
scanResults.enqueue(...)

并且数组在正常情况下(案例 1)可以正常填充,但在这种情况下(案例 2),它会抛出错误。

我认为这是因为空值。我尝试使用自定义类型适配器,但它没有解决问题,在 GsonBuilder 上设置 serializeNulls() 也没有解决问题。

有人知道解决办法吗?

编辑:经过更多调试后,由于某种原因,服务器似乎在 CASE 2 中返回字符串而不是字符串数组。当我手动访问链接时,我确实看到了字符串数组,但由于某种原因,响应是字符串。

最佳答案

"Expected BEGIN_ARRAY but was STRING"意味着 Gson 正在解析的字符是一个 ",但它期望一个 [(因为你正在尝试解析列表)。由于输入与预期输入不对应,因此 Gson 必须失败。从 Gson 的角度来看,案例 2 输入与案例 1 输入没有任何不同(如果空值是一个问题, 错误消息会说一些类似的东西)。

由于此输入不受信任(它来自第三方服务器?),您应该在解析调用周围添加一些错误处理代码,以解决输入格式错误的可能性。至少在失败时记录接收到的输入会立即清楚地表明您没有收到预期的数组。

关于java - GSON 应为 BEGIN_ARRAY 但在第 1 行错误为 STRING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41952677/

相关文章:

java - 使用 GSON 的空字段的默认值

java - 使用 Gson 访问 JsonString

Java 文件不会在所有行的末尾保存新行

java - 使用不同关键字将 JSON 映射到 Java 对象

java - Eclipse Juno 和 Maven 插件因项目更新而失败

java - 在android中更快地下载给定url的图像

java - ViewPager 未从服务器获取图像

android - 如何强制 ViewGroup 从屏幕上绘制?

java - 从手工制作的 hibernate 映射文件转向注释是否值得?

java - 配置 bazel 使用特定 JVM 版本构建/测试