我正在尝试使用从API返回的Retrofit和GSON来解析String数组:
这就是响应通常的样子(案例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(...)
并且数组在正常情况下(CASE 1)填充正常,但在这种情况下(CASE 2),它会抛出错误。
我认为这是因为空值。我尝试使用自定义类型适配器,但它没有解决问题,同时在GsonBuilder上设置serializeNulls()并没有解决问题。
有人知道解决方案吗?
编辑:经过一些调试后,似乎服务器因为某种原因在CASE 2而不是String数组中返回一个字符串。当我手动访问链接时,我确实看到了字符串数组,但由于某种原因,响应是String。答案 0 :(得分:1)
&#34; 预计BEGIN_ARRAY但是STRING &#34;表示Gson正在解析的字符是"
,但它期望[
(因为您正在尝试解析列表)。由于输入与预期输入不对应,Gson必须失败。从Gson的角度来看,案例2输入与案例1输入没有任何不同(如果空值是一个问题,则错误消息会说明这种情况)。
由于此输入不受信任(它来自第三方服务器?),您应该在解析调用周围添加一些错误处理代码,以便考虑输入的可能性畸形。至少记录失败时收到的输入将立即表明您没有收到预期的阵列。