Gson 会忽略 JsonElement 字段上的 @JsonAdapter 吗?
Does Gson ignore @JsonAdapter on JsonElement fields?
我有一个对象要序列化,使用 Gson
:
class User {
String firstname;
String lastname;
JsonElement opaqueData;
}
在顶级对象级别,我希望 Gson
忽略 null
字段(例如,如果 lastname
是 null
,则不应序列化)。
但是在字段 opaqueData
中,我希望 null
s 被序列化,因为它应该是一个不透明的数据块。所以使用 new GsonBuilder().serializeNulls().create().toJson(user)
是行不通的。
但是@JsonAdapter
也不行
class User {
String firstname;
String lastname;
@JsonAdapter(NullAdapter.class)
JsonElement opaqueData;
}
class NullAdapter extends TypeAdapter<JsonElement> {
@Override
public void write(JsonWriter out, JsonElement value) throws IOException {
out.jsonValue(new GsonBuilder().serializeNulls().create().toJson(value));
}
@Override
public JsonElement read(JsonReader in) throws IOException {
// TODO Auto-generated method stub
return null;
}
}
Gson 似乎忽略了适配器。
这是预期的行为吗?如何在不为整个用户创建适配器的情况下实现这一点 class 然后手动序列化每个字段?
Gson
懒得去适应它的内部数据类型 JsonElement
。我不知道是否有任何意义,因为 JsonElement
kind 是改编的结果。
看一眼 source code of Gson 您可以看到两个顶级方法:
对于任何对象
public String toJson(Object src) {
if (src == null) {
return toJson(JsonNull.INSTANCE);
}
return toJson(src, src.getClass());
}
我认为在不复制其余代码的情况下,上述方法一在其执行路径中搜索和设置适配器(以及查询适配器工厂)是显而易见的。但是还有这样的方法:
对于 JsonElement
public String toJson(JsonElement jsonElement) {
StringWriter writer = new StringWriter();
toJson(jsonElement, writer);
return writer.toString();
}
并且对于该执行路径,没有搜索也没有设置任何适配器,因为 JsonElement
不再适用。
因此,当 Gson
命中任何 JsonElement
时,它只是将 ti 序列化为格式化字符串,您无法使用任何适配器影响它。
如果你真的需要序列化类似的东西,也许你可以为 JsonElement
制作一个包装器 class,比如:
public class JsonElementWrapper {
public JsonElement jsonElement;
}
并调整您的 TypeAdapter
以适应“空”或实际值。
我有一个对象要序列化,使用 Gson
:
class User {
String firstname;
String lastname;
JsonElement opaqueData;
}
在顶级对象级别,我希望 Gson
忽略 null
字段(例如,如果 lastname
是 null
,则不应序列化)。
但是在字段 opaqueData
中,我希望 null
s 被序列化,因为它应该是一个不透明的数据块。所以使用 new GsonBuilder().serializeNulls().create().toJson(user)
是行不通的。
但是@JsonAdapter
也不行
class User {
String firstname;
String lastname;
@JsonAdapter(NullAdapter.class)
JsonElement opaqueData;
}
class NullAdapter extends TypeAdapter<JsonElement> {
@Override
public void write(JsonWriter out, JsonElement value) throws IOException {
out.jsonValue(new GsonBuilder().serializeNulls().create().toJson(value));
}
@Override
public JsonElement read(JsonReader in) throws IOException {
// TODO Auto-generated method stub
return null;
}
}
Gson 似乎忽略了适配器。
这是预期的行为吗?如何在不为整个用户创建适配器的情况下实现这一点 class 然后手动序列化每个字段?
Gson
懒得去适应它的内部数据类型 JsonElement
。我不知道是否有任何意义,因为 JsonElement
kind 是改编的结果。
看一眼 source code of Gson 您可以看到两个顶级方法:
对于任何对象
public String toJson(Object src) {
if (src == null) {
return toJson(JsonNull.INSTANCE);
}
return toJson(src, src.getClass());
}
我认为在不复制其余代码的情况下,上述方法一在其执行路径中搜索和设置适配器(以及查询适配器工厂)是显而易见的。但是还有这样的方法:
对于 JsonElement
public String toJson(JsonElement jsonElement) {
StringWriter writer = new StringWriter();
toJson(jsonElement, writer);
return writer.toString();
}
并且对于该执行路径,没有搜索也没有设置任何适配器,因为 JsonElement
不再适用。
因此,当 Gson
命中任何 JsonElement
时,它只是将 ti 序列化为格式化字符串,您无法使用任何适配器影响它。
如果你真的需要序列化类似的东西,也许你可以为 JsonElement
制作一个包装器 class,比如:
public class JsonElementWrapper {
public JsonElement jsonElement;
}
并调整您的 TypeAdapter
以适应“空”或实际值。