2013-06-27 50 views
6

我得到這個問題,我不想解決問題,而是找到辦法說GSON「跳過錯誤並繼續」解析:GSON避免JsonSyntaxException返回部分映射

Can't parses json : java.lang.IllegalStateException: 
    Expected a string but was BEGIN_OBJECT at line 1 column 16412 

代碼使用:

JsonReader reader = new JsonReader(new StringReader(data)); 
reader.setLenient(true); 
Articles articles = gson.create().fromJson(reader, Articles.class); 

該數據是(爲了簡化):Articles-> Pages-> medias.fields。當前錯誤中的一個字段被定義爲字符串,但是我正在接收一個對象(但它只是一次出現)。我不能到處都增加了保護,所以我的問題是:「是有一個跳躍,並繼續在GSON

我想避免JsonSysntaxException與GSON時,有一個節點上的問題,我希望至少取回部分數據解析。對我來說,我將不得不數據的99.999%,只有我的錯字段爲空...我知道這似乎不乾淨,但我會啓用「嚴格模式」爲單元測試或持續集成檢測問題和生產我會啓用一個「軟模式」,所以我的應用程序可以啓動(即使服務器端出現錯誤)我不能說我的定製,你的應用程序無法啓動,因爲一篇文章有​​一個無效的數據

GSON有一個 」跳過並繼續出現錯誤「?

+0

我們展示的代碼? – ajduke

+0

u能張貼在網絡服務的響應,這將有助於更多的解決烏爾問題 – KOTIOS

+0

我添加的代碼,我不想定勢這個問題,但找到一種方法,不會觸發此異常時,只有葉/節點受到格式不良的影響。可能嗎 ? – Gros

回答

2

我認爲答案很簡單:沒有,一般不能。

由於如果事情是錯的庫遞歸解析性質,它會拋出某種異常。如果您可以發佈問題的SSCCE來試驗是否可以創建處理更好的異常的定製類型適配器,那將會很有趣。

1

這裏是解決方案: 你必須創建TypeAdapterFactory這將允許您攔截默認TypeAdapter, 但還是留給你訪問默認TypeAdapter作爲代表。 然後,您可以嘗試使用默認TypeAdapter中的委託讀取值,並根據需要處理意外數據。

 public Gson getGson() { 

       return new GsonBuilder() 
          .registerTypeAdapterFactory(new LenientTypeAdapterFactory()) 
       .create(); 
      } 


     class LenientTypeAdapterFactory implements TypeAdapterFactory { 

       public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 

        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 

        return new TypeAdapter<T>() { 

         public void write(JsonWriter out, T value) throws IOException { 
          delegate.write(out, value); 
         } 

         public T read(JsonReader in) throws IOException { 
          try { //Here is the magic 
//Try to read value using default TypeAdapter 
           return delegate.read(in); 
          } catch (JsonSyntaxException e) { 
//If we can't in case when we expecting to have an object but array is received (or some other unexpected stuff), we just skip this value in reader and return null 
           in.skipValue(); 
           return null; 
          } 
         } 
        }; 
       } 
    }