如何在自定义反序列化器Gson中小写JsonElement值?
我的class级有一个自定义反序列化器,如下所示:
private class HolderDeserializer implements JsonDeserializer { @Override public Holder deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { Type mapType = new TypeToken<Map>() {}.getType(); // in the below data map, I want value to be stored in lowercase // how can I do that? Map 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>() {}.getType(); Map response = gson.fromJson(jsonLine, responseType);
在我的{"linkedTo":"COUNT"}
方法中, 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... } }
首先,建议使用Gson TypeAdapter而不是JsonDeserializer 。 所以我将用它来回答你的问题:
新应用程序应该更喜欢TypeAdapter,其流API比此接口的树API更有效。
更多信息。
问题:如何在反序列化之前修改json内容?
解决方案之一:在反序列化之前预处理json内容并修改其中的一些内容。
我们如何使用TypeAdapter实现此目的:定义自定义TypeAdapter
,在其read
方法(在反序列化之前调用)获取json内容并修改内容。
代码示例:
定义TypeAdapterFactory
和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()); } } } } }; } };
我们在反序列化之前添加了一个额外的进程。 我们从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);
输出:
这是您的问题的类似答案。