指定要在Ktor中序列化为JSON的类字段

时间:2019-06-15 22:03:12

标签: json kotlin gson ktor json-serialization

如示例中所示,

Serving JSON content in Ktor as described in HTTP API - Quick Start - Ktor适用于常见的集合(列表,地图等)和数据类。但是,如果我要序列化不是数据类且具有要排除的字段的类,如何指定要序列化的字段及其序列化名称?假设我正在使用Gson,是否可以像直接使用Gson序列化类对象一样进行操作?

1 个答案:

答案 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,所以您可以从字段中获得很多属性,例如名称和注释。这样可以进行非常精细的控制。

最后,您也可以为反序列化以及addDeserializationExclusionStrategysetExclusionStrategies设置反序列化策略。