Gson将List<String>反序列化为realmList<RealmString>
Gson deserialization of List<String> into realmList<RealmString>
我正在使用 gson 改造将我的 json 反序列化为领域对象。这在大多数情况下都非常有效。处理
时出现问题
RealmList(String(or any other basic data type))
由于 Realm 不支持 RealmList,其中 E 不扩展 Realm 对象,我将 String 包装在 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 TypeAdapter
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;
}
但是我仍然遇到了 IllegalStateException
2334-2334/com.qualcomm.qlearn.app E//PersonService.java:71﹕ main com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was NAME at line 1 column 3 path $.
我之前尝试过 RealmList、RealmString 适配器,但无济于事。
到目前为止我设法找到的唯一解决方法是 https://github.com/realm/realm-java/issues/620#issuecomment-66640786
还有更好的选择吗?
我的 gson typeAdapter 是罪魁祸首。
上面的错误是因为我没有正确地将 json 反序列化为 RealmPerson,第一个字段不是字符串,因此
in.nextString()
很无聊。
我看了一些示例代码,它击中了我,我不必使用
in.beginObject() and in.endObject()
反序列化字符串。以下代码有效。
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;
}
}
希望这对某人有所帮助。
错误消息“Expected a string but was NAME
”可以通过在实际 json 对象(这是一个String
在你的情况下)。
你可以看看Android documentation for JsonReader。它有详细的解释和代码片段。您还可以查看文档中示例代码片段中的 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;
}
如果有帮助请告诉我。
It is better to use JsonSerializer
and JsonDeserializer
rather than TypeAdapter
为您的 RealmObject
,因为 2 个原因:
它们允许您将 RealmObject
的(反)序列化委托给默认的 Gson(反)序列化器,这意味着 您不需要编写样板自己.
有 a weird bug in Gson 2.3.1 可能会在反序列化期间导致 WhosebugError
(我自己尝试了 TypeAdapter
方法并遇到了这个错误)。
方法如下(将 Tag
替换为您的 RealmObject
class):
(注意 下面的 context.serialize
和 context.deserialize
等同于 gson.toJson
和 gson.fromJson
, 这意味着我们 不需要自己解析Tag
class。)
RealmList<Tag>
的解析器 + 序列化程序:
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;
}
}
标签class:
@RealmClass
public class Tag extends RealmObject {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
然后用 Gson 注册你的转换器 class:
Gson gson = new GsonBuilder()
.registerTypeAdapter(new TypeToken<RealmList<Tag>>() {}.getType(),
new TagRealmListConverter())
.create();
我需要一个用于将 Arraylist 转换为 RealmList 的 jackson 序列化器和反序列化器
我正在使用 gson 改造将我的 json 反序列化为领域对象。这在大多数情况下都非常有效。处理
时出现问题RealmList(String(or any other basic data type))
由于 Realm 不支持 RealmList,其中 E 不扩展 Realm 对象,我将 String 包装在 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 TypeAdapter
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;
}
但是我仍然遇到了 IllegalStateException
2334-2334/com.qualcomm.qlearn.app E//PersonService.java:71﹕ main com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was NAME at line 1 column 3 path $.
我之前尝试过 RealmList、RealmString 适配器,但无济于事。 到目前为止我设法找到的唯一解决方法是 https://github.com/realm/realm-java/issues/620#issuecomment-66640786 还有更好的选择吗?
我的 gson typeAdapter 是罪魁祸首。 上面的错误是因为我没有正确地将 json 反序列化为 RealmPerson,第一个字段不是字符串,因此
in.nextString()
很无聊。
我看了一些示例代码,它击中了我,我不必使用
in.beginObject() and in.endObject()
反序列化字符串。以下代码有效。
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;
}
}
希望这对某人有所帮助。
错误消息“Expected a string but was NAME
”可以通过在实际 json 对象(这是一个String
在你的情况下)。
你可以看看Android documentation for JsonReader。它有详细的解释和代码片段。您还可以查看文档中示例代码片段中的 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;
}
如果有帮助请告诉我。
It is better to use JsonSerializer
and JsonDeserializer
rather than TypeAdapter
为您的 RealmObject
,因为 2 个原因:
它们允许您将
RealmObject
的(反)序列化委托给默认的 Gson(反)序列化器,这意味着 您不需要编写样板自己.有 a weird bug in Gson 2.3.1 可能会在反序列化期间导致
WhosebugError
(我自己尝试了TypeAdapter
方法并遇到了这个错误)。
方法如下(将 Tag
替换为您的 RealmObject
class):
(注意 下面的 context.serialize
和 context.deserialize
等同于 gson.toJson
和 gson.fromJson
, 这意味着我们 不需要自己解析Tag
class。)
RealmList<Tag>
的解析器 + 序列化程序:
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;
}
}
标签class:
@RealmClass
public class Tag extends RealmObject {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
然后用 Gson 注册你的转换器 class:
Gson gson = new GsonBuilder()
.registerTypeAdapter(new TypeToken<RealmList<Tag>>() {}.getType(),
new TagRealmListConverter())
.create();
我需要一个用于将 Arraylist 转换为 RealmList 的 jackson 序列化器和反序列化器