GSON避免JsonSyntaxException返回部分映射

时间:2013-06-27 10:54:20

标签: java android json parsing gson

我遇到了这个问题,我不想解决这个问题,但是想找GSON“跳过错误并继续”解析:

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);

数据是(简化):文章 - > Pages-> medias.fields。当前错误中的一个字段被定义为字符串,但我正在接收一个对象(但同样只有一次出现)。我不能在任何地方添加保护,所以我的问题是:“是否有跳过并继续在GSON中?

当节点出现问题时,我希望避免使用GSON的JsonSysntaxException,我希望至少能够检索解析的部分数据。在我的情况下,我将拥有99.999%的数据,只有我的错误字段为空...我知道它似乎不干净,但我会启用“严格模式”进行单元测试或连续集成以检测问题和生产我会启用“软模式”,以便我的应用程序可以启动(即使服务器端出错)。我无法对我的自定义说,您的应用无法启动,因为文章有无效数据。

GSON是否有“跳过并继续出错”?

2 个答案:

答案 0 :(得分:3)

以下是解决方案: 你必须创建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;
                            }
                        }
                    };
                }
    }

答案 1 :(得分:2)

我认为答案很简单:不,一般不能。

由于库的递归解析特性,如果出现问题,它会引发某种异常。如果您可以发布问题的SSCCE进行实验,如果可以创建一个处理更好例外的自定义类型适配器,那将会很有趣。