如何在自定义反序列化器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内容并修改内容。

代码示例:

定义TypeAdapterFactoryTypeAdapter ;

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

输出:

在此处输入图像描述

这是您的问题的类似答案。