Обслуживание содержимого JSON в Ktor, как описано в HTTP API — быстрый старт — Ktor, как показано в примерах, работает для обычных коллекций (списков, карт и т. д.) и классов данных. Однако, если я хочу сериализовать класс, который не является классом данных и имеет поля, которые я хочу исключить, как мне указать поля, которые нужно сериализовать, и их сериализованные имена? Предположим, что я использую Gson, могу ли я сделать это так же, как сериализовать объект класса, используя Gson напрямую?
Укажите поля класса для сериализации в JSON в Ktor
Ответы (1)
Насколько мне известно, используя Gson, у вас есть несколько вариантов.
<сильный>1. Использование перехода
Если вы пометите поле @Transient
(transient
в Java), оно будет исключено из сериализации:
data class Foo(
@Transient val a: Int,
val b: Int)
Здесь b
будет сериализован, а a
— нет.
У этого есть огромный недостаток — почти каждый фреймворк в java учитывает @Transient
, и иногда вы не хотите, чтобы Gson сериализовал его, но вы можете захотеть, например, сохранить его в базе данных (если вы будете использовать один и тот же класс для обоих). Чтобы учесть это, есть еще один вариант, использующий @Expose
.
<сильный>2. Использование экспозиции
Вам нужно создать экземпляр 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
.
GsonBuilder
в качестве получателя в блоке gson: install(ContentNegotiation) { gson { // Configure GsonBuilder here } }
- person avolkmann; 17.06.2019
@SerializedName
, чтобы указать сериализованное имя JSON, верно?
- person Shreck Ye; 18.06.2019