Java GSON避免JsonSyntaxException返回部分映射

Java GSON避免JsonSyntaxException返回部分映射,java,android,json,parsing,gson,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(tr

我遇到了这个问题,我不想解决这个问题,但想办法告诉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);
数据是(为了简化):文章->页面->媒体字段。当前错误中的一个字段被定义为string,但我正在接收一个对象(但它也只是一次出现)。我无法在任何地方添加保护,因此我的问题是:“GSON中是否有跳过并继续?

当一个节点出现问题时,我希望通过GSON避免JsonSysntaxException,我希望至少检索解析的部分数据。在我的情况下,我会有99.999%的数据,只有我错误的字段为null…我知道它看起来不干净,但我会启用“严格模式”对于单元测试或连续集成来检测问题,在生产中,我会启用“软模式”,这样我的应用程序就可以启动(即使服务器端出错)。我不能对我的客户说,你的应用程序无法启动,因为一篇文章有无效数据


GSON是否有“出错时跳过并继续”的问题?我认为答案很简单:不,通常不能

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

以下是解决方案: 您必须创建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;
                            }
                        }
                    };
                }
    }
公共Gson getGson(){ 返回新的GsonBuilder() .registerTypeAdapterFactory(新的LenientTypeAdapterFactory()) .create(); } 类LenientTypeAdapterFactory实现TypeAdapterFactory{ 公共类型适配器创建(Gson Gson,TypeToken类型){ final-TypeAdapter-delegate=gson.getDelegateAdapter(这个,类型); 返回新的TypeAdapter(){ public void write(JsonWriter out,T值)抛出IOException{ 委托。写出(输出、值); } 公共T读取(JsonReader in)引发IOException{ 试试看{//这是魔术 //尝试使用默认类型适配器读取值 返回delegate.read(in); }捕获(JsonSyntaxException e){ //若我们不能在希望有一个对象但接收到数组(或其他一些意外的东西)的情况下,只需在reader中跳过这个值并返回null in.skipValue(); 返回null; } } }; } }
您能否发布web服务的响应,这将有助于解决您的问题。我添加了代码,我不想解决此问题,但我想找到一种方法,在只有叶/a节点受到错误格式影响时,不会触发此异常。有可能吗?@Gros我们需要查看您试图解析的实际JSON代码@MikO我的问题不是什么问题,而是帮助我解决这个具体问题。我知道问题在哪里以及如何解决。我的问题更多,如果json中的某个地方存在结构问题,那么在GSON中是否有“跳过并继续”的方法?有很多对象,所以我不想忽略未使用的信息。为了提供一个概述,我有一些文章(数组)->带页面->带媒体。一种媒体将变量作为字符串,但在json中它是一个对象(但只有一次)。注意:问题可能会出现在其他地方,因此我无法详细说明。@Gros好的,但您至少应该解释一下您所说的结构问题是什么意思,因为解决方案可能会有所不同。。。它是无效的JSON吗?或者是JSON中某个地方的对象结构不符合预期?还是怎样一些JSON代码示例可以在这里提供帮助。。。