我的课程有自定义反序列化器,如下所示:
private class HolderDeserializer implements JsonDeserializer<Holder> {
@Override
public Holder deserialize(JsonElement json, Type type, JsonDeserializationContext context)
throws JsonParseException {
Type mapType = new TypeToken<Map<String, String>>() {}.getType();
// in the below data map, I want value to be stored in lowercase
// how can I do that?
Map<String, String> data = context.deserialize(json, mapType);
return new Holder(data);
}
}
这就是我在创建Gson对象时注册反序列化器的方法:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Holder.class, new HolderDeserializer());
Gson gson = gsonBuilder.create();
最后,像这样解析我的JSON:
Type responseType = new TypeToken<Map<String, Holder>>() {}.getType();
Map<String, Holder> response = gson.fromJson(jsonLine, responseType);
在我的deserialize
方法中,json
的值与此{"linkedTo":"COUNT"}
一样,然后以{linkedTo=COUNT}
的形式加载到数据地图中。我想知道data
地图的所有值是否都可以小写,而不是{linkedTo=COUNT}
,它应该自动存储在数据地图中,如{linkedTo=count}
这样?
有没有办法在Gson中自动执行此操作?
更新
以下是我的JSON内容:
{
"abc": {
"linkedTo": "COUNT",
// possibly more data...
},
"plmtq": {
"linkedTo": "TITLE",
"decode": "TRUE",
// possibly more data...
}
}
答案 0 :(得分:2)
首先,建议使用Gson TypeAdapter代替JsonDeserializer。所以我将用它来回答你的问题:
新应用程序应该更喜欢TypeAdapter,其流API是 比这个界面的树API更有效。
问题:如何在反序列化之前修改json内容?
其中一个解决方案:在反序列化之前预处理json内容并修改其中的一些内容。
我们如何使用TypeAdapter实现此目的:定义自定义TypeAdapter
,以read
方法(在反序列化之前调用)获取json内容并修改内容。
代码示例:
定义TypeAdapterFactory
和TypeAdapter
;
TypeAdapterFactory myCustomTypeAdapterFactory = new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); //
return new TypeAdapter<T>() {
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<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> 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());
}
}
}
}
};
}
};
我们在反序列化之前添加了额外的进程。我们从json内容中获取entrySet
并更新了linkedTo
键的值。
工作样本:
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);
<强>输出:强>