【问题标题】:GSON avoid the JsonSyntaxException return the partial mappingGSON 避免 JsonSyntaxException 返回部分映射
【发布时间】:2013-06-24 20:11:41
【问题描述】:

我遇到了这个问题,我不想解决这个问题,但想办法对 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);

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

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

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

【问题讨论】:

  • 你能把网络服务的回复贴出来吗,这将有助于解决你的问题
  • 我添加了代码,但我不想修复这个问题,但是当只有一个叶子/一个节点受到错误格式的影响时,我想找到一种不触发这个异常的方法。有可能吗?
  • @Gros 我们需要查看您尝试解析的实际 JSON 代码!
  • @MikO 我的问题不是问题所在,帮助我解决这个具体问题。我知道问题出在哪里以及如何解决。我的问题更多,如果 json 中某处存在结构问题,是否有办法在 GSON 中“跳过并继续”?有很多对象,所以我不想过去无用的信息。为了概述,我有一些文章(数组)-> 带有页面-> 带有媒体。一种将变量作为字符串媒体,但在 json 中它是一个对象(但只有一次)。注意:问题可能出现在其他地方,所以我无法具体说明。
  • @Gros 好的,但是您至少应该解释一下 结构问题 是什么意思,因为取决于解决方案可能会有所不同...是吗无效的 JSON?还是 JSON 中某个对象的结构与预期不符?要不然是啥?一些 JSON 代码示例可以在这里提供帮助...

标签: java android json parsing gson


【解决方案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;
                            }
                        }
                    };
                }
    }

【讨论】:

    【解决方案2】:

    我认为答案很简单:不,通常不能。

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

    【讨论】:

      猜你喜欢
      • 2012-10-04
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 2019-12-07
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多