【问题标题】:Deserializing JSON object to string field with GSON使用 GSON 将 JSON 对象反序列化为字符串字段
【发布时间】:2016-01-18 12:04:11
【问题描述】:

我有一个 POJO,其中包含一个已经序列化 JSON 的字符串字段。性能是这里的关键,所以我想避免解析它然后重新序列化它。

public class SomeObject {
    String someString = "";
    String jsonString = "{\"one\":4, \"two\":\"hello\"}";
    long someLong = 4;
}

目前 GSON 将其序列化如下:

{ "someString":"", "jsonString":"{\"one\":4, \"two\":\"hello\"}", "someLong":4 }

我写了一个 JsonSerializer/Deserializer 希望使用 @JsonAdapter 注解,但它只支持 TypeAdapter 或 TypeAdapterFactory。

public class JsonStringTypeAdapter implements JsonSerializer<String>, JsonDeserializer<String> {

    @Override
    public JsonElement serialize(String t, Type type, JsonSerializationContext jsc) {
        return new JsonParser().parse(t).getAsJsonObject();
    }

    @Override
    public String deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
        return je.getAsString();
    }

    @Override
    public void write(JsonWriter writer, String t) throws IOException {
        writer.jsonValue(t);
    }

}

所以我编写了以下简单的 TypeAdapter,它非常适合序列化,但我不知道如何在 TypeAdapter 中将 Json 对象反序列化为 String。

public class JsonStringTypeAdapter extends TypeAdapter<String> {

    @Override
    public void write(JsonWriter writer, String t) throws IOException {
        writer.jsonValue(t);
    }

    @Override
    public String read(JsonReader reader) throws IOException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}

我知道 Jackson 对此有注释。用 GSON 做这件事有什么想法吗?

【问题讨论】:

  • 您对 POJO 的序列化有何期待??
  • { "someString":"", "jsonString":{"one":4, "two":"hello"}, "someLong":4 }
  • 如果你用“"”替换转义的引号字符,它会做你想要的吗?您也可以尝试 \u0022 Unicode 转义序列。不是我知道的答案,只是建议替代方案。
  • 它仍然会将其括在引号中并将其序列化为字符串。它需要序列化string -&gt; json object 和反序列化json object -&gt; string 我序列化工作得很好,但我被反序列化卡住了。

标签: java json gson


【解决方案1】:

使用 TypeAdapterFactory 解决了。

public class JsonStringTypeAdapterFactory implements TypeAdapterFactory {

   @Override
   public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tokenType) {
       if (!JsonString.class.isAssignableFrom(tokenType.getRawType())) return null;

       return (TypeAdapter<T>) new JsonStringTypeAdapter(gson);
   }

}

并完成读取方法

/* The JsonStringTypeAdapter writes the raw string value directly to the JSON output
 *  this offers great performance by avoiding parsing then reserialising
 * Note: Care must be taken to ensure the input JsonString is well formed JSON.
 *       Otherwise, when it is deserialised, errors will occur.
 *
 * @author adamjohnson
 */
public class JsonStringTypeAdapter extends TypeAdapter<JsonString> {

    private final Gson gson;
    public JsonStringTypeAdapter(Gson gson) {
        this.gson = gson;
    }

    @Override
    public void write(JsonWriter writer, JsonString t) throws IOException {
        /* check for invalid json string, if so create empty object. */
        if (t.value().equals("")) {
            writer.jsonValue("{}");
        } else /* write raw string directly to json output */ {
            writer.jsonValue(t.value());
        }
    }

    @Override
    public JsonString read(JsonReader reader) throws IOException {
        return new JsonString(gson.getAdapter(JsonElement.class).read(reader).getAsString());
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-03
    • 2013-01-18
    • 2017-08-02
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多