在 Ktor 中指定要序列化为 JSON 的类字段
Posted
技术标签:
【中文标题】在 Ktor 中指定要序列化为 JSON 的类字段【英文标题】:Specify class fields to be serialized to JSON in Ktor 【发布时间】:2019-10-30 01:17:51 【问题描述】:Serving JSON content in Ktor as described in HTTP API - Quick Start - Ktor,如示例中所示,适用于常见的集合(列表、地图等)和数据类。但是,如果我想序列化一个不是数据类并且具有要排除的字段的类,如何指定要序列化的字段及其序列化名称?假设我用的是Gson,能不能和直接用Gson序列化一个类对象一样?
【问题讨论】:
像往常一样使用 gson api。非数据类应该可以正常工作。你也可以试试看。如果您需要更多帮助,请提供更具体的问题。 【参考方案1】:据我所知,使用 Gson,您有几个选择。
1.使用瞬态
如果你用@Transient
(Java 中的transient
)标记一个字段,这将从序列化中排除:
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
设置此策略。
【讨论】:
值得注意的是,ktor 将GsonBuilder
作为 gson 块中的接收者传递:install(ContentNegotiation) gson // Configure GsonBuilder here
所以我也可以只使用@SerializedName
指定JSON 序列化名称对吗?
是的。事实上,在 android 应用程序中我们总是这样做,因为变量的名称通常会被混淆,然后序列化的 json 会被完全破坏。我认为您不会在后端执行此操作,但如果您想要一个不同的名称,它仍然很方便。以上是关于在 Ktor 中指定要序列化为 JSON 的类字段的主要内容,如果未能解决你的问题,请参考以下文章
如何在应用脚本高级服务中指定要在 Google DataStudio 中使用的数组字段?