I have a POJO with a String field that is already serialized JSON. Performance is key here, so I want to avoid parsing it and then re-serializing it.
public class SomeObject {
String someString = "";
String jsonString = "{\"one\":4, \"two\":\"hello\"}";
long someLong = 4;
}
Currently GSON serialises it like so:
{ "someString":"", "jsonString":"{\\"one\\":4, \\"two\\":\\"hello\\"}", "someLong":4 }
I wrote a JsonSerializer/Deserializer in hopes of using the @JsonAdapter annotation, but it only supports TypeAdapter or 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);
}
}
So I wrote the following simple TypeAdapter that works perfectly for serialisation, but I can't work out how to deserialise a Json object to String in a TypeAdapter.
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.");
}
}
I know Jackson has an annotation for this. Any ideas for doing it with GSON?
Solved it using 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);
}
}
And completing the read method
/* 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());
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.