如何使用gson缓存的json字符串?

时间:2014-01-11 18:48:08

标签: java serialization gson

我有一个保存在缓存的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)。

用例就像拥有一个非常大的对象,只有一个字段可能会改变,你必须经常序列化 - 所以不必重新序列化整个对象,只有属性是很好的已经改变了。

由于

2 个答案:

答案 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()) {

希望它有意义。