Вроде.По какой-то причине Gson обнаруживает конфликты имен при десериализации экземпляров Map
, но не выполняет такую проверку для пакетов данных или JsonElement
и его потомков (поэтому вы не можете написать десериализатор на основе дерева JSON для их обнаружения).
Учитывая,
{
"x": true,
"x": false
}
final class Foo {
@SuppressWarnings("UnnecessaryBoxing")
final boolean x = Boolean.valueOf(false);
}
final Foo foo = gson.fromJson(jsonReader, Foo.class);
if ( !foo.x ) {
throw new AssertionError();
}
Это не работает для стандарта JsonReader
.Тем не менее, вы можете обойти это на самом низком уровне.Это немного сложно и не очень хорошо оптимизировано, но охватывает все возможные десериализаторы (и это, вероятно, объясняет, почему Gson ведет себя по-разному в разных десериализаторах: каждый такой десериализатор должен выполнять эту проверку сам и может просто пропустить работу).
final class StrictNamesJsonReader
extends JsonReader {
private final Stack<Set<String>> nameStack = new Stack<>();
private Set<String> names;
private StrictNamesJsonReader(final Reader reader) {
super(reader);
}
static JsonReader of(final Reader reader) {
return new StrictNamesJsonReader(reader);
}
@Override
public void beginObject()
throws IOException {
super.beginObject();
names = new HashSet<>();
nameStack.add(names);
}
@Override
public String nextName()
throws IOException {
final String name = super.nextName();
if ( !names.add(name) ) {
throw new JsonSyntaxException("Detected duplicate property name " + name + " in " + names + " at " + this);
}
return name;
}
@Override
public void endObject()
throws IOException {
super.endObject();
nameStack.pop();
names = !nameStack.isEmpty() ? nameStack.peek() : null;
}
}
Как видите, эта реализация JsonReader
сама управляет обнаружением дубликатов имен и выдает что-то вроде следующего исключения
Exception in thread "main" com.google.gson.JsonSyntaxException: Detected duplicate property name x in [x] at StrictNamesJsonReader at line 3 column 5 path $.x
, если обнаружены дубликаты.
Вы можете запросить пересмотрвопрос на https://github.com/google/gson/pull/649 хотя.Я действительно считаю, что десериализаторы - это неправильный способ обнаружения дубликатов, и JsonReader
должно быть улучшено в отличие от того, что предлагается в этом PR.