欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[Java] gson反序列化(json字符串转对象)遇到空对象/空数组的解决方法

程序员文章站 2022-05-11 19:53:07
...

com.google.gson.JsonSyntaxException:Java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT
[Java] gson反序列化(json字符串转对象)遇到空对象/空数组的解决方法

在使用gson反序列化到Java对象时遇到以上问题。
直译就是gson在反序列化时期待的是BEGIN_ARRAY([)这个字符,但是收到的却是BEGIN_OBJECT({)

debug时把对应的字符串粘贴出来,找到错误信息中所写的列数。

我的第一反应是反序列化生成json的javabean时生成错了,我又重新在网页工具中生成了一次javabean。但是发现还是有问题

正常的数据结构是这样
[Java] gson反序列化(json字符串转对象)遇到空对象/空数组的解决方法
但是其中有一些例外情况。
[Java] gson反序列化(json字符串转对象)遇到空对象/空数组的解决方法
如图反序列化时simple对象中的属性没有了。所以本该解析成对象但是,只能解析为空数组

网上查找解决方案后,发现可以继承TypeAdapter类,并重写write(序列化)和read(反序列化)方法解决。
[Java] gson反序列化(json字符串转对象)遇到空对象/空数组的解决方法
Simple实体类代码

public class Simple {

    private String tag;
    private String enText;
    private String chText;

	以及getter和setter等方法
}

重新反序列化方法

public class SimpleTypeAdapter extends TypeAdapter<Simple> {

    /**
     * * 流式序列化(速度快),将序列化后的值写到流对象中
     */
    @Override
    public void write(JsonWriter out, Simple value) throws IOException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        out.beginObject(); //流式序列化成对象开始
        out.name("chText").value(value.getChText());
        out.name("enText").value(value.getEnText());
        out.name("tag").value(dateFormat.format(value.getTag()));//格式化日期输出
        out.endObject(); //流式序列化结束
    }

    /**
     * 反序列化,从json流对象中读取
     */
    @Override
    public Simple read(JsonReader in) throws IOException {
        Simple simple = new Simple();
        if (in.peek() == JsonToken.BEGIN_ARRAY) {

            in.beginArray();

            if (in.peek() == JsonToken.BEGIN_OBJECT) {
                in.beginObject();
                while (in.hasNext()) {
                    switch (in.nextName()) {
                        case "tag":
                            simple.setTag(in.nextString());
                            break;
                        case "chText":
                            simple.setChText(in.nextString());
                            break;
                        case "enText":
                            simple.setEnText(in.nextString());
                            break;
                    }
                }
                in.endObject();
            }
            if (in.peek() == JsonToken.END_ARRAY) {
                in.endArray();
            }
        }
        return simple;
    }
}

但是这种方法最后还没有成功,因为这个json字符串还有很多其他问题,不整齐。

另外经前辈提醒,我只是用其中某一个字段。所以不一定非要使用对象完整的反序列化出来。可以通过JsonObject和JsonArray直接读想要的属性值机壳

最后通过JsonObject和JsonArray得到了想要的结果。

参考

https://blog.csdn.net/Ever69/article/details/86469320

相关标签: Java