I get a json that has "field" field.
If the "field" has data, then there is an OBJECT that has many (about 20) other fields that are also objects. I can deserialize them without any problems.
But if "field" has no data, it is an empty ARRAY (I know it's crazy, but that's the response from server and I can't change it). Something like this:

空时:

"extras":[

]

Has some data:

"extras": {
    "22":{ "name":"some name" },
    "59":{ "name":"some other name" },
    and so on...
}

So, when there if no data (empty array), I obviously get the exception

Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 4319

I tried to use custom JavaDeserializer:

public class ExtrasAdapter implements JsonDeserializer<Extras> {
    @Override
    public Extras deserialize(JsonElement json, Type typeOf,
        JsonDeserializationContext context) throws JsonParseException {
        try {
            JsonObject jsonObject = json.getAsJsonObject();
            // deserialize normally

            // the following does not work, as it makes recursive calls
            // to the same function
            //return context.deserialize(jsonObject,
            //                       new TypeToken<Object>(){}.getType());
        } catch (IllegalStateException e) {
            return null;
        }
    }
}

我按照以下方式阅读json

Gson gsonDecoder = new GsonBuilder().registerTypeAdapter(Extras.class, new ExtrasAdapter();
// httpResponse contains json with extras filed. 
Reader reader = new InputStreamReader(httpResponse.getEntity().getContent());
Extras response = gsonDecoder.fromJson(reader, Extras.class);

I don't want to deserialize all 20 fields manually (I know this is an option), I just want to call context.defaultDeserialize(), or something like that.
Once again: I don't have any problems deserializing normal json, creating custom objects, registering custom TypeAdapters, custom JavaDeserializers. It all works already. I need only some solution for handling a data, that can be both ARRAY and OBJECT.
Thanks for any help.

======================


The Joey's answer works perfect. That right the thing I was looking for. I'll post my code here.

public class SafeTypeAdapterFactory 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 {
                try {
                    delegate.write(out, value);
                } catch (IOException e) {
                    delegate.write(out, null);
                }
            }
            public T read(JsonReader in) throws IOException {
                try {
                    return delegate.read(in);
                } catch (IOException e) {
                    Log.w("Adapter Factory", "IOException. Value skipped");
                    in.skipValue();
                    return null;
                } catch (IllegalStateException e) {
                    Log.w("Adapter Factory", "IllegalStateException. Value skipped");
                    in.skipValue();
                    return null;
                } catch (JsonSyntaxException e) {
                    Log.w("Adapter Factory", "JsonSyntaxException. Value skipped");
                    in.skipValue();
                    return null;
                }
            }
        };
    }
}

推荐答案

Try using GSON >= 2.2.1 and look for the TypeAdapterFactory class.

这将使您能够在反序列化对象之前判断对象,并应用自定义代码,同时避免递归.

下面是您可以使用的getDelegateAdapter的一个示例.

Json相关问答推荐

Elasticsearch Go客户端错误:无效的SON格式:在中间件中索引文档时出错

Golang JSON Date Tim.Date()测试请求

服务器不返回JSON

属性错误:';ActivitiesClient';对象没有属性';base_url';

Oracle JSON 查询中的动态列列表

VSCode 为 python 文件添加标尺,但不为 C 文件添加标尺.为什么?

Vega-Lite规范:尽管在规范中提供了数据,但显示空图表

Shell脚本空格转义

通过一个序列化器更新多个模型数据

使用 Jolt 变换将平面 json 转换为具有多个数组的嵌套 Json

Vue 3如何将参数作为json发送到axios get

如何用 Xidel 正确读取这个 JSON 文件?

PowerShell - JSON/PsCustomObject - 为什么我的数组被扁平化为一个对象?

在 JSON 字符串中react i18n 换行符

使用 GSON 解析嵌套的 JSON 数据

错误未判断调用put(K, V)作为原始类型java.util.HashMap的成员

在视图中将 .Net 对象转换为 JSON 对象

TypeError: b'1' 不是 JSON 可序列化的

如何将 MongoDB 查询转换为 JSON?

如何使用 Json.NET 反序列化可以是两种不同数据类型的 JSON 属性