Преобразование имен свойств стиля JSON в имена Java CamelCase с помощью GSON


107

Я использую GSON для преобразования получаемых данных JSON в объект Java. Он неплохо работает во всех моих тестах. Проблема в том, что у наших реальных объектов есть некоторые свойства с именем is_online. GSON отображает их только в том случае, если они названы полностью равными, было бы неплохо, если бы GSON преобразовал имена в Java camel case isOnline.

Кажется, что это возможно при создании данных JSON, регистр верблюда преобразуется в слова, разделенные подчеркиванием, в JSON. Но я не могу найти способ указать это наоборот.


5
Предлагаю принять ответ
Жан Вальжан 01

Ответы:


313

Я обнаружил, что следующий параметр отлично работает при чтении json с подчеркнутыми атрибутами и использовании верблюжьей рамки в моих моделях.

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create()

2
Отличный ответ, спасибо! @janusz, если какой-либо из этих ответов вам помог, отметьте их как принятые.
sufinawaz

1
Если у вас есть случай, когда имя содержит два символа подчеркивания, первое подчеркивание игнорируется. Ex. this_key_has__two_underscores будет преобразовано в thisKeyHas_TwoUnderscores и то же самое наоборот. Ключевым моментом является FieldNamingPolicy, где в перечислении написано «нижний регистр» с подчеркиванием, а здесь преобразованное имя имеет верхний регистр с подчеркиванием (_T).
Deepak GM

Очень просто, избавляет меня от необходимости аннотировать кучу полей!
Уильям Т. Маллард,

99

Вы можете использовать SerializedNameаннотацию:

@SerializedName("field_name_in_json")
private final String fieldNameInJava;

Примечание: если вы уже установили FieldNamingPolicy, SerializedNameбудут перезаписаны его настройки для этого конкретного поля (очень удобно для особых случаев).


2

Имейте в виду, что ваш пример - крайний случай. Если у вас есть свойство foo, его получатель должен называться getFoo, а если у вас есть свойство с именем foo_bar, его получатель должен называться getFooBar, однако в вашем примере вы сопоставляете логическое и логическое значение специальные соглашения об именах в java. Примитивное логическое свойство с именем online должно иметь метод получения с именем isOnline, а НЕ getOnline или, что еще хуже, getIsOnline. Логический объект-оболочка (то есть Boolean) не должен следовать этому особому случаю, а свойство с именем 'online' должно иметь метод получения с именем 'getOnline'.

Следовательно, наличие логических свойств с 'is' в имени - это крайний случай, когда вы захотите удалить этот конкретный префикс во время преобразования. В обратном направлении ваш код может захотеть проверить объект json как на необработанное имя свойства, так и на версию is_XXX.


2

Я думаю, что вам нужно здесь . Используя аннотации, вы можете сообщить GSON, что mySuperCoolField на самом деле называется this_field_is_fun в JSON, и он правильно распакует его. По крайней мере, я думаю, что это работает и для десериализации.

Если это не сработает, вы можете использовать пользовательские JsonSerializer / JsonDeserializers, которые отлично работают, но вам нужно обновить их для изменений в вашем классе (например, когда вы добавляете поле). Вы теряете авто-магию.

Проще всего (что было бы уродливо, но очень чисто и просто, если первое предложение не сработало) - просто назвать поле так, чтобы сделать GSON счастливым, и добавить дополнительные методы доступа с именами, которые вам нравятся. , например

public boolean isXXX() {return this.is_XXX;}

легкая вещь - это то, что я делаю сейчас, и она отлично работает. Весь уродливый, нетипичный код в стиле java спрятан в классах данных, и никто извне его не увидит. Но это все еще меня немного придирает :)
Януш
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.