Укажите поля класса для сериализации в JSON в Ktor - PullRequest
0 голосов
/ 16 июня 2019

Обслуживание содержимого JSON в Ktor, как описано в HTTP API - Quick Start - Ktor , как показано в примерах, работает для общих коллекций (списков, карт и т. Д.) И классов данных. Однако, если я хочу сериализовать класс, который не является классом данных и имеет поля, которые я хочу исключить, как мне указать поля для сериализации и их сериализованные имена? Предположим, что я использую Gson, могу ли я сделать это так же, как и сериализацию объекта класса с использованием Gson напрямую?

1 Ответ

2 голосов
/ 17 июня 2019

Насколько мне известно, используя Gson, у вас есть несколько вариантов.

1.Использование Transient

Если вы пометите поле с помощью @Transient (transient в Java), это будет исключено из сериализации:

data class Foo(
    @Transient val a: Int,
    val b: Int)

Здесь b будетСериализуется и a не будет.

Это имеет огромный недостаток - почти каждый фреймворк в java учитывает @Transient, и иногда вы не хотите, чтобы Gson сериализовал его, но вы можете захотетьнапример, сохранить его в базе данных (если вы используете один и тот же класс для обоих).Чтобы учесть это, есть еще один вариант, используя @Expose.

2.Использование Expose

Вам необходимо создать экземпляр gson, используя построитель:

val gson = GsonBuilder()
    .excludeFieldsWithoutExposeAnnotation()
    .create();

Теперь поля без @Expose не будут сериализованы:

data class Foo(
    val a: Int,
    @Expose val b: Int)

Опять же, a не будет сериализован, но b будет.

3.Использование стратегий исключения

Более продвинутым методом является использование стратегий исключения.Это позволяет загружать самоанализ на полях.От пользовательских аннотаций до имени или типа поля.

Опять же, вам нужно создать gson со строителем:

val gson = GsonBuilder()
    .addSerializationExclusionStrategy(strategyInstance)
    .create();

И вы определяете стратегию, такую ​​как:

object : ExclusionStrategy() {
  override fun shouldSkipField(field: FieldAttributes): Boolean {
  }

  override fun shouldSkipClass(clazz: Class<*>): Boolean {
  }
}

внутри shouldSkipField вы возвращаете true, если вы не хотите сериализовать поле, и false, когда вы это делаете.Поскольку он получает FieldAttributes, вы можете получить много свойств из поля, таких как имя и аннотации.Это позволяет очень тонко контролировать.

Наконец, вы можете установить эту стратегию и для десериализации, и для обоих - addDeserializationExclusionStrategy и setExclusionStrategies.

...