如何在自定义解串器Gson中使用JsonElement值? [英] How to lowercase the JsonElement value in the custom deserializer Gson?

查看:264
本文介绍了如何在自定义解串器Gson中使用JsonElement值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  private class HolderDeserializer实现了JsonDeserializer< Holder> {

@Override
public Holder deserialize(JsonElement json,Type type,JsonDeserializationContext context)
throws JsonParseException {

Type mapType = new TypeToken< Map< ; String,String>>(){} .getType();
//在下面的数据图中,我希望将值存储为小写
//我该怎么做?
Map< String,String> data = context.deserialize(json,mapType);
返回新的Holder(数据);




$ b $ p
$ b

这就是我在注册我的反序列化器时创建Gson对象:

  GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(Holder.class,new HolderDeserializer());
Gson gson = gsonBuilder.create();

最后,解析我的JSON,如下所示:

 键入responseType = new TypeToken< Map< String,Holder>>(){} .getType(); 
地图< String,Holder> response = gson.fromJson(jsonLine,responseType);

在我的 deserialize 方法中, code> json 就像这样 {linkedTo:COUNT} ,然后将它载入数据映射为 {linkedTo = COUNT} 。我想看看是否有任何方法可以使 data map的所有值都小写,所以不是这个 {linkedTo = COUNT} ,它应该自动保存在数据图中的这个 {linkedTo = count}



有没有办法在Gson中自动执行此操作?

更新:



以下是我的JSON内容:

  {
abc:{
linkedTo:COUNT,
//可能更多数据...
},
plmtq:{
linkedTo:TITLE,
decode:TRUE,
//可能更多数据...
}
}


这是类似的问题答案。


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

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

And this is how I register my deserializer when creating the Gson object:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Holder.class, new HolderDeserializer());
Gson gson = gsonBuilder.create();

And finally, parsing my JSON like this:

Type responseType = new TypeToken<Map<String, Holder>>() {}.getType();
Map<String, Holder> response = gson.fromJson(jsonLine, responseType);

In my deserialize method, value of json is coming as like this {"linkedTo":"COUNT"} and then it get loaded into data map as {linkedTo=COUNT}. I wanted to see if there is any way by which all the value of data map can be lowercase so instead of this {linkedTo=COUNT}, it should get stored like this {linkedTo=count} in data map automatically?

Is there any way to do this in Gson itself automatically?

Update:

Below is my JSON content:

{
    "abc": {
        "linkedTo": "COUNT",
        // possibly more data...
    },
    "plmtq": {
        "linkedTo": "TITLE",
        "decode": "TRUE",
        // possibly more data...
    }
}

解决方案

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

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.

这篇关于如何在自定义解串器Gson中使用JsonElement值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆