使用GSON将JSON对象反序列化为字符串字段

时间:2016-01-18 12:04:12

标签: java json gson

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

          <xsl:for-each  select="DOCUMENT/ROWSET/ROW[count(. |             key('bykey1453107264684', ORDER_ID)[1]) = 1]">
<fo:table-row  keep-with-next="always"  background-color="#ffffff"  height="3.43cm"   >
    <fo:table-cell>
    <!-- b7241a65976545a29cb3adaf7e81d5ab -->
        <fo:block  keep-together="always"><xsl:value-of select="LINE_NO"></xsl:value-of></fo:block>
    </fo:table-cell>
        <fo:table-cell  >
    <!-- 6193eb7f045b4c7f84a62ec78f9b8610 -->
    <fo:block    keep-together="always" ><xsl:value-of select="PARTICULAR"></xsl:value-of></fo:block>
    </fo:table-cell>
        <fo:table-cell >
    <!-- b851391f97d943ae8ea9ad24544887fd -->
    <fo:block  keep-together="always"><xsl:value-of select="TOTAL_AMT">               </xsl:value-of></fo:block>
    </fo:table-cell>
        <fo:table-cell>
    <fo:block></fo:block>        </fo:table-cell>
    </fo:table-row>
        <fo:table-row keep-together="always" >
    <fo:table-cell  >
    <fo:block></fo:block>        </fo:table-cell>
        <fo:table-cell  >
    <!-- 6a4ae7636f7240cfb324c03b7ff502ac -->
    <fo:block   keep-together="always">Total</fo:block>
    </fo:table-cell>
        <fo:table-cell  >
    <!-- efcabc0ed27b4db397079743e4caee5f -->
    <fo:block  keep-together="always"><xsl:value-of select="LINE_TOTAL_AMT"></xsl:value-of></fo:block>
    </fo:table-cell>
        <fo:table-cell>
            <fo:block></fo:block>        </fo:table-cell>
    </fo:table-row>
    </xsl:for-each>
    </fo:table-body>
    </fo:table>
    </xsl:if>


    <!-- END Area Detail -->
    </fo:block>
    </fo:table-cell>
    </fo:table-row>

目前GSON将其序列化为:

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

为了使用@JsonAdapter注释,我编写了一个JsonSerializer / Deserializer,但它只支持TypeAdapter或TypeAdapterFactory。

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

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

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);
    }

}

我知道杰克逊对此有一个注释。有关使用GSON的任何想法吗?

1 个答案:

答案 0 :(得分:0)

使用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());
    }

}