当前位置: 首页 > 知识库问答 >
问题:

Gson将List反序列化为realmList

孟财
2023-03-14

我正在使用gson进行改造,将json反序列化为领域对象。这在大多数情况下都很有效。处理问题时会出现麻烦

RealmList(字符串(或任何其他基本数据类型))

由于Realm不支持RealmList,其中E不扩展Realm对象,所以我将字符串包装在RealmObject中。

public class RealmString extends RealmObject {
  private String val;

  public String getValue() {
    return val;
  }

  public void setValue(String value) {
    this.val = value;
  }
}

我的领域对象如下

    public class RealmPerson extends RealmObject {
    @PrimaryKey
    private String userId;
    ...
    private RealmList<RealmString> stringStuff;
    private RealmList<SimpleRealmObj> otherStuff;

    <setters and getters>
   }

SimpleRealmObj工作正常,因为它只有字符串元素

    public class SimpleRealmObj extends RealmObject {
    private String foo;
    private String bar;
       ...
    }

如何反序列化stringStuff?我试过使用gson类型适配器

public class RealmPersonAdapter extends TypeAdapter<RealmPerson> {
    @Override
    public void write(JsonWriter out, RealmPerson value) throws IOException {
        out.beginObject();
        Log.e("DBG " + value.getLastName(), "");
        out.endObject();
    }

    @Override
    public RealmPerson read(JsonReader in) throws IOException {
        QLRealmPerson rList = new RealmPerson();
        in.beginObject();
        while (in.hasNext()) {
            Log.e("DBG " + in.nextString(), "");
        }
        in.endObject();

        return rList;
    }

不过我还是遇到了非法州例外

2334-2334/com.qualcomm.qlearn.appE//个人ervice.java:71︰主要com.google.gson.JsonSynTaxExcelie:java.lang.IllegalStateExcelie:预期一个字符串,但在第1行第3列路径$的名称。

我之前尝试过RealmList、RealmString适配器,但没有成功。到目前为止,我找到的唯一解决办法是https://github.com/realm/realm-java/issues/620#issuecomment-66640786还有更好的选择吗?

共有3个答案

子车海
2023-03-14

我的gson typeAdapter就是罪魁祸首。上面的错误被认为是因为我没有正确地将json反序列化为Reamperson,第一个字段不是字符串,因此

in.next字符串

他正在怀孕。

我看了一些示例代码,突然想到,我不必使用

in.begin对象()和in.end对象()

对字符串进行反序列化。下面的代码有效。

public class QLRealmStringAdapter extends TypeAdapter<QLRealmString> {
@Override
public void write(JsonWriter out, QLRealmString value) throws IOException {
    Log.e("DBG " + value.getValue(), "");
    out.value(value.getValue());
}

@Override
public RealmString read(JsonReader in) throws IOException {
    RealmString rString = new RealmString();
    if (in.hasNext()) {
        String nextStr = in.nextString();
        System.out.println("DBG " + nextStr);
        rString.setValue(nextStr);
    }

    return rString;
}

}

希望这对别人有帮助。

柯琛
2023-03-14

可以通过在实际json对象(在您的情况下是一个String)之前的JsonReader中检索json对象的名称来解决错误消息期望一个字符串,但却是NAME

您可以查看JsonReader的Android文档。它有详细的解释和代码片段。您还可以查看文档中示例代码片段中的readMessage方法。

我已经修改了你的read方法,使之符合我的想法。注意:我没有测试代码,所以可能有一些小错误。

@Override
public RealmPerson read(JsonReader in) throws IOException {
    RealmPerson rList = new RealmPerson();
    in.beginObject();
    String name = "";
    while (in.hasNext()) {
        name = in.nextName();

        if (name.equals("userId")) {
            String userId = in.nextString();
            // update rList here 
        } else if (name.equals("otherStuff")) {
            // since otherStuff is a RealmList of RealmStrings,
            // your json data would be an array
            // You would need to loop through the array to retrieve 
            // the json objects
            in.beginArray();
            while (in.hasNext()) {
                // begin each object in the array
                in.beginObject();
                name = in.nextName();
                // the RealmString object has just one property called "value"
                // (according to the code snippet in your question)
                if (name.equals("val")) {
                    String val = in.nextString();
                     // update rList here 
                } else {
                    in.skipValue();
                }
                in.endObject();
            }
            in.endArray();
        } else {
            in.skipValue();
        }
    }
    in.endObject();


    return rList;
}

如果有帮助,请告诉我。

后易安
2023-03-14

对于RealmObject,最好使用JsonSerializerJsonDeserializer而不是TypeAdapter,原因有二:

>

Gson 2.3.1中有一个奇怪的错误,可能会在反序列化过程中导致StackOverflow Error(我自己尝试了TypeAdapter方法,遇到了这个错误)。

以下是如何(用RealmObject类替换Tag):

(注意下面的context.serializecontext.deserialize相当于gson.toJsongson.fromJson,这意味着我们不需要自己解析标记类。)

RealmList的解析器序列化程序

public class TagRealmListConverter implements JsonSerializer<RealmList<Tag>>,
        JsonDeserializer<RealmList<Tag>> {

    @Override
    public JsonElement serialize(RealmList<Tag> src, Type typeOfSrc,
                                 JsonSerializationContext context) {
        JsonArray ja = new JsonArray();
        for (Tag tag : src) {
            ja.add(context.serialize(tag));
        }
        return ja;
    }

    @Override
    public RealmList<Tag> deserialize(JsonElement json, Type typeOfT,
                                      JsonDeserializationContext context)
            throws JsonParseException {
        RealmList<Tag> tags = new RealmList<>();
        JsonArray ja = json.getAsJsonArray();
        for (JsonElement je : ja) {
            tags.add((Tag) context.deserialize(je, Tag.class));
        }
        return tags;
    }

}

标记类:

@RealmClass
public class Tag extends RealmObject {
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

然后用Gson注册你的转换器类:

Gson gson = new GsonBuilder()
        .registerTypeAdapter(new TypeToken<RealmList<Tag>>() {}.getType(),
                new TagRealmListConverter())
        .create();

 类似资料:
  • 问题内容: 我想通过Google Gson传输列表对象,但是我不知道如何反序列化泛型类型。 看了这个之后我尝试了什么(BalusC的答案): 但是后来我在日食中遇到了一个错误,说“新的List(){}类型必须实现继承的抽象方法…”,如果我使用快速修复方法,则会得到20个以上的方法存根的怪物。 我很确定有一个更简单的解决方案,但是我似乎找不到它! 编辑: 我现在有 但是,我确实在“ fromJson

  • 问题内容: 我正在使用gson改造,将json反序列化为领域对象。在大多数情况下,这非常有效。处理时出现麻烦 RealmList(String(或任何其他基本数据类型)) 由于Realm不支持E不扩展Realm对象的RealmList,因此我将String封装在RealmObject中。 我的领域对象如下 SimpleRealmObj正常工作,因为它只有String元素 如何反序列化stringS

  • 首先,我想说这是一个大学项目。 我有三节课<代码>订单抽象类和从订单继承的和类。 我使用Gson序列化/反序列化子类,但我遇到了一点问题。订单类有一个字段,gson使用该字段来确定订单类型,DineIn或Delivery。 序列化工作得很好。问题是,每当我尝试反序列化时,类型字段值都不会读取,并且总是设置为null,即使它存在于JSON文件中。当有很多字段时,就会发生这种情况,因为当我尝试在较小的

  • 由于Realm无法处理升级类型,包括s,所以我正试图实现一个,就像这个问题一样。 问题是,我对为什么会出现以下错误感到困惑: W/系统。呃:com。谷歌。格森。JsonSyntaxException:java。lang.IllegalStateException:应为BEGIN_对象,但为字符串 这是Json的一部分: 我的RealmString: 改装Pojo的一部分: 以及反序列化程序: 我在

  • 我使用Json-Jackson序列化/反序列化我的对象,并且与内置类配合得很好。 字符串、int等非常好。但是现在我必须序列化/反序列化以特定方式构建的对象。遵循声明: 如果我使用标准的序列化器/反序列化,它会向我显示一条错误消息,例如“java.lang.不支持的操作异常...”,因此它无法序列化/反序列化bobjs。 我如何以一般方式做到这一点,所以我不写3个序列化器/反序列化器,而是只告诉J

  • 问题内容: 由于要执行处理的业务逻辑,因此我正在实现自定义。但是某些部分可以解析为标准方式。这是否可能- 我自己处理一些元素,并让一些嵌套元素自动处理? 这是JSON: 这是项的自定义反序列化器: 现在,我想让GSON解析枚举。我可以自己完成,这只是几行代码,但是我更愿意库做很多。 问题答案: …但是我希望图书馆尽其所能。 好吧,只需使用Gson。 有数据传输对象模式,尤其是Gson映射类,可以完