I have a custom deserializer for my class as shown below:
private class HolderDeserializer implements JsonDeserializer {
@Override
public Hold
Firstly, it is suggested to use Gson TypeAdapter instead of JsonDeserializer. So I'm going to answer your question with it:
New applications should prefer TypeAdapter, whose streaming API is more efficient than this interface's tree API.
More information.
Question: How can we modify the json content before deserialization ?
One of the solutions: Preprocess the json content before deserialization and modify some of its contents.
How can we achive this with TypeAdapter: Define a custom TypeAdapter
, get the json content at its read
method (which is called just before the deserialization) and modify the content.
Code sample:
Define a TypeAdapterFactory
and a TypeAdapter
;
TypeAdapterFactory myCustomTypeAdapterFactory = new TypeAdapterFactory() {
@Override
public TypeAdapter create(Gson gson, TypeToken type) {
final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
final TypeAdapter delegate = gson.getDelegateAdapter(this, type); //
return new TypeAdapter() {
public void write(JsonWriter out, T value) throws IOException {
JsonElement tree = delegate.toJsonTree(value);
beforeWrite(value, tree);
elementAdapter.write(out, tree);
}
public T read(JsonReader in) throws IOException {
JsonElement tree = elementAdapter.read(in);
afterRead(tree);
return delegate.fromJsonTree(tree);
}
/**
* Modify {@code toSerialize} before it is written to
* the outgoing JSON stream.
*/
protected void beforeWrite(T source, JsonElement toSerialize) {
}
/**
* Modify {@code deserialized} before it is parsed
*/
protected void afterRead(JsonElement deserialized) {
if(deserialized instanceof JsonObject) {
JsonObject jsonObject = ((JsonObject)deserialized);
Set> entrySet = jsonObject.entrySet();
for(Map.Entry entry : entrySet){
if(entry.getValue() instanceof JsonPrimitive) {
if(entry.getKey().equalsIgnoreCase("linkedTo")) {
String val = jsonObject.get(entry.getKey()).toString();
jsonObject.addProperty(entry.getKey(), val.toLowerCase());
}
} else {
afterRead(entry.getValue());
}
}
}
}
};
}
};
We've added an extra process before deserialization. We get the entrySet
from json content and updated linkedTo
key's value.
Working sample:
String jsonContent = "{\"abc\":{\"linkedTo\":\"COUNT\"},\"plmtq\":{\"linkedTo\":\"TITLE\",\"decode\":\"TRUE\"}}";
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapterFactory(myCustomTypeAdapterFactory);
Gson gson = gsonBuilder.create();
Map mapDeserialized = gson.fromJson(jsonContent, Map.class);
Output:
This is the similar answer for your question.