GSON:如何从Json获得不区分大小写的元素?

| 当
JSON
对象包含
jsonKey
并传递给方法时,下面显示的代码可以很好地工作。我想知道...是否有办法获取分配给键的不区分大小写的表示形式的值? 例:
public String getOutputEventDescription(JsonElement outputEvent) throws ParserException {
    return retrieveString(outputEvent, DESCRIPTION);
}
无论Description是否定义为\“ Description \”,\“ description \”或\“ DeScRipTIOn \”,都应该起作用
protected String retrieveString(JsonElement e, String jsonKey) throws ParserException {

JsonElement value = e.getAsJsonObject().get(jsonKey);

if (value == null) {
    throw new ParserException(\"Key not found: \" + jsonKey);
}

if (value.getAsString().trim().isEmpty()) {
    throw new ParserException(\"Key is empty: \" + jsonKey);
}

return e.getAsJsonObject().get(jsonKey).getAsString();
}
    
已邀请:
        不幸的是,在当前的实现中似乎没有办法做到这一点。如果查看Gson源代码,更具体地说是JsonObject实现,您将看到基础数据结构是链接的哈希映射。 get调用仅调用地图上的get,后者依次使用哈希码和键的equals方法查找要查找的对象。 唯一的解决方法是为您的密钥强制执行一些命名约定。最简单的方法是将所有键都强制转换为小写。如果您需要大小写混合的键,则将遇到更多困难,并且需要编写更复杂的算法来转换键,而不是简单地调用jsonKey.toLowerCase()。     
        不幸的是,用ѭ5来注册
FieldNamingStrategy
并没有多大用处,因为它只能以与期望相反的方向进行转换:从Java字段名称到JSON元素名称。它不能合理地用于您的目的。 (详细地: 转换请求的结果在
FieldNamingStrategy.translateName(Field)
处结束,转换后的名称用于从ѭ7get获得关联的JSON元素,ѭ7has具有
LinkedHashMap<String, JsonElement>
,称为
members
,将JSON元素名称映射到其关联值。转换后的名称用作
members
get(String)
方法的参数,Gson没有提供任何机制使此最终调用不区分大小写。 在
members
映射中填充了对由
Streams.parseRecursive(JsonReader)
进行的
JsonObject.add(String, JsonElement)
的调用,并从ѭ15retrieve检索到的JSON元素名称用作\'members \'的键。 (
JsonReader
使用的字符与JSON中的字符完全相同,但找到转义字符\'\\\'的情况除外。)在整个调用堆栈中,Gson都不提供用于更改填充
members
的键的机制,例如,全部制成小写或全部大写。
FieldNamingPolicy
的工作方式与此相同。) 合理的解决方案可能是按照以下几句话简单地使用自定义解串器。 input.json:
[
 {\"field\":\"one\"},
 {\"Field\":\"two\"},
 {\"FIELD\":\"three\"},
 {\"fIElD\":\"four\"}
]
Foo.java:
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.Map.Entry;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(MyClass.class, new MyTypeAdapter());
    Gson gson = gsonBuilder.create();
    MyClass[] myObjects = gson.fromJson(new FileReader(\"input.json\"), MyClass[].class);
    System.out.println(gson.toJson(myObjects));
  }
}

class MyClass
{
  String field;
}

class MyTypeAdapter implements JsonDeserializer<MyClass>
{
  @Override
  public MyClass deserialize(JsonElement json, Type myClassType, JsonDeserializationContext context)
      throws JsonParseException
  {
    // json = {\"field\":\"one\"}
    JsonObject originalJsonObject = json.getAsJsonObject();
    JsonObject replacementJsonObject = new JsonObject();
    for (Entry<String, JsonElement> elementEntry : originalJsonObject.entrySet())
    {
      String key = elementEntry.getKey();
      JsonElement value = originalJsonObject.get(key);
      key = key.toLowerCase();
      replacementJsonObject.add(key, value);
    }
    return new Gson().fromJson(replacementJsonObject, MyClass.class);
  }
}
或者,您可以首先处理原始JSON,以将所有元素名称更改为大小写相同(全部为小写或全部为大写)。然后,将更改后的JSON传递给Gson进行反序列化。当然,这会减慢JSON处理的速度。 如果您能够为您的项目更改Gson代码,那么为获得最有效结果而需要更改的部分可能是在
JsonReader
中调用
name = nextString((char) quote);
。由于ѭ23also也用于获取JSON元素值,因此我可能会对其进行复制以获取名称,然后进行一些小的更改以将元素名称全部强制为小写或全部大写。当然,这种方法然后将您的项目锁定到一个Gson版本,否则您将需要重复此更改以升级到更新的Gson版本。 不幸的是,在杰克逊的情况下。不幸的是,带有“ 24”的转换的工作方式几乎相同:它们从Java字段名称转换为JSON元素名称。所有可用的“ 25”更改都不会自定义“ 26”来强制将JSON元素名称全部大写或全部小写。     
        我面临类似的问题。我这样做是为了解决这个问题。 (将所有键替换为其对应的小写字母版本,并将所有小写字母字段都放在匹配的类中)。希望这可以帮助。
 input = input.replaceAll(\"\\\\s\",\"\");
        Matcher m = Pattern.compile(\"\\\"\\\\b\\\\w{1,}\\\\b\\\"\\\\s*:\").matcher(input);
        StringBuilder sanitizedJSON = new StringBuilder();
        int last = 0;
        while (m.find()) {
            sanitizedJSON.append(input.substring(last, m.start()));
            sanitizedJSON.append(m.group(0).toLowerCase());
            last = m.end();
        }
        sanitizedJSON.append(input.substring(last));

        input = sanitizedJSON.toString();
    

要回复问题请先登录注册