我有一个保存在缓存的json字符串上的类:
class Foo {
private transient String cachedJson; // value = [ "john", "mary" ]
private List<String> names;
}
当我使用gson序列化Foo类的一个实例时,有没有一种方法可以使用自定义序列化器,只需为“names”字段编写缓存字符串,而不是让序列化器再次重新序列化所有内容?类似的东西:
public class CustomParserFoo implements
JsonSerializer<Foo>
{
@Override
public JsonElement serialize(Foo src,
Type typeOfSrc,
JsonSerializationContext context)
{
JsonObject element = new JsonObject();
if (src.cachedJson != null) {
// cached value present, use it.
element.addProperty("names", src.cachedJson);
} else {
// have to really serialize it.
element.addProperty("names", ...);
}
return element;
}
}
上面的问题是gson会尝试转义你提供的字符串(已经是json-escaped)。
用例就像拥有一个非常大的对象,只有一个字段可能会改变,你必须经常序列化 - 所以不必重新序列化整个对象,只有属性是很好的已经改变了。
由于
答案 0 :(得分:2)
使用Gson进行序列化时,您正在创建一个解析树,而Gson正在编写;不幸的是,它没有提供告诉它通过你的类中的字段的功能,因为它已经是JSON。
您必须使用com.google.gson.JsonParser
课程为您提供JsonElement
:
JsonElement cachedArray = new JsonParser().parse(src.cachedJson);
element.addProperty("names", cachedArray);
因为这意味着您要对缓存的JSON进行反序列化,以便gson稍后可以写出整个解析树,所以将JSON缓存为JsonArray
可能更有意义。
编辑添加:值得一提的是Jackson JSON解析器确实提供了此序列化功能。您可以使用@JsonRawValue
对字段或方法进行注释,然后将其传递给它。
答案 1 :(得分:0)
在我们的服务中,我们每个请求花费200毫秒来执行缓存对象的gson序列化。我们改变了我们的架构来缓存json字符串并直接返回它们。
您必须重新打包gson库并创建自己的:
onMessage: function (e) {
new Vue({
el: '#messages',
data: {
messages: e.data,
done: true
}
});
}
这将允许您在TypeAdapters类中更改此行:
package repackaged.com.google.gson;
public class JsonElementCache extends JsonElement {
String cache;
public JsonElementCache(String cache) {
this.cache = cache;
}
public String getCache() {
return cache;
}
@Override
JsonElement deepCopy() {
return new JsonElementCache(this.cache);
}
}
这也在JsonWriter.class中:
@Override public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) {
if (value instanceof JsonElementCache) {
out.writeCached(((JsonElementCache) value).getCache());
}
else if (value == null || value.isJsonNull()) {
希望它有意义。