How to lowercase the JsonElement value in the custom deserializer Gson?

后端 未结 1 1741
夕颜
夕颜 2021-01-29 00:09

I have a custom deserializer for my class as shown below:

private class HolderDeserializer implements JsonDeserializer {

  @Override
  public Hold         


        
1条回答
  •  再見小時候
    2021-01-29 01:13

    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.

    0 讨论(0)
提交回复
热议问题