К сожалению, регистрация FieldNamingStrategy
с помощью GsonBuilder
не принесет большой пользы, поскольку она переводит только в противоположном направлении: от имени поля Java к элементу JSON название. Он не может быть разумно использован для ваших целей.
(Подробно:
Результат запроса на перевод заканчивается на FieldNamingStrategy.translateName(Field)
, где переведенное имя используется для получения связанного элемента JSON из JsonObject
, который имеет LinkedHashMap<String, JsonElement>
, называемый members
, сопоставляя имена элементов JSON с их связанные ценности. Переведенное имя используется в качестве параметра для get(String)
метода members
, и Gson не предоставляет никакого механизма для того, чтобы этот последний вызов не учитывал регистр.
Карта members
заполняется вызовами JsonObject.add(String, JsonElement)
, сделанными из Streams.parseRecursive(JsonReader)
, с именем элемента JSON, полученным из JsonReader
, используемого в качестве ключа для «members». (JsonReader
использует символы в точности так, как они есть в JSON, за исключением того, что находится escape-символ '\'.) В этом стеке вызовов Gson не предоставляет механизма для изменения ключей, используемых для заполнения members
. Например, должен быть весь нижний регистр или весь верхний регистр.
A 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 для своего проекта, то, вероятно, часть, которую нужно изменить для получения наиболее эффективного результата, - это вызов name = nextString((char) quote);
в JsonReader
. Поскольку nextString(char)
также используется для получения значения элемента JSON, я, вероятно, просто сделаю его копию для получения имени, а затем внесу небольшие изменения, чтобы заставить имена элементов указывать все в нижнем или верхнем регистре. Конечно, этот подход затем привязывает ваш проект к одному выпуску Gson, иначе вам придется повторить это изменение, чтобы перейти на более новый выпуск Gson.
С Джексоном ситуация выглядит, к сожалению, похожей. Переводы с PropertyNamingStrategy
работают, к сожалению, почти одинаково: они переводятся из имени поля Java в имя элемента JSON. Ни одно из доступных изменений JsonParser.Feature
не настроит JsonParser
для принудительной установки имен элементов JSON в верхний или нижний регистр.