Serving JSON content in Ktor as described in HTTP API - Quick Start - Ktor适用于常见的集合(列表,地图等)和数据类。但是,如果我要序列化不是数据类且具有要排除的字段的类,如何指定要序列化的字段及其序列化名称?假设我正在使用Gson,是否可以像直接使用Gson序列化类对象一样进行操作?
答案 0 :(得分:2)
据我所知,使用Gson,您有两个选择。
1。使用瞬变
如果您使用@Transient
(在Java中为transient
)标记字段,则该序列将从序列化中排除:
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
设置反序列化策略。