对Kotlin数据类使用Jackson@JsonProperty注解

tyky79it  于 2022-11-08  发布在  Kotlin
关注(0)|答案(7)|浏览(165)

Kotlin1.2.10Jackson模块-kotlin:2.9.0
下面是一个例子:

data class CurrencyInfo(
        @JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)

@JsonInclude(JsonInclude.Include.NON_NULL)
data class CurrencyInfoItem(
        @JsonProperty("iso_4217") var iso4217: String?,
        @JsonProperty("name") var name: String?,
        @JsonProperty("name_major") var nameMajor: String?,
        @JsonProperty("name_minor") var nameMinor: String?,
        @JsonProperty("i_ma_currency") var iMaCurrency: Int?,
        @JsonProperty("i_merchant_account") var iMerchantAccount: Int?,
        @JsonProperty("i_x_rate_source") var iXRateSource: Int?,
        @JsonProperty("base_units") var baseUnits: Double?,
        @JsonProperty("min_allowed_payment") var minAllowedPayment: Int?,
        @JsonProperty("decimal_digits") var decimalDigits: Int?,
        @JsonProperty("is_used") var isUsed: Boolean?
)

当我尝试反序列化这个数据类时,我得到以下结果:

{"currency_info":{"iso_4217":"CAD","name":"Canadian Dollar","imerchantAccount":0,"ixrateSource":2}}

正如您所看到的,最后两个选项被错误地反序列化了。这个问题可以通过直接向getter @get:JsonProperty添加注解来解决。但是,根据Jacksondocs,@JsonProperty应该分配给getter/setter/fields
所以,我想问一下,是否有一种可靠的方法来注解Kotlin中的Jackson属性,以使其具有正确的序列化/反序列化(此外,我的所有数据类都是自动生成的,因此很难分别为getter和setter创建一些两行/三行注解)
否则,这个问题能通过一些Jackson设置来解决吗?
根据下面的答案,以下内容适合我

private val mapper = ObjectMapper().registerKotlinModule()
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE)
y53ybaqx

y53ybaqx1#

代码中的@JsonProperty注解都放在数据类的私有字段中,默认情况下Jackson不会扫描私有字段中的注解。

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
data class CurrencyInfo(
    @JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)

或者,您可以移动访问器方法上的注解:

data class CurrencyInfo(
    @get:JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
vaqhlq81

vaqhlq812#

您可以执行以下操作:

data class CurrencyInfo @JsonCreator constructor (
        @param:JsonProperty("currency_info") 
        @get:JsonProperty("currency_info")
        val currencyInfo: CurrencyInfoItem?
)

以上代码转换为java为:

public final class CurrencyInfo {
   @Nullable
   private final String currencyInfo;

   @JsonProperty("currency_info")
   @Nullable
   public final String getCurrencyInfo() {
      return this.currencyInfo;
   }

   @JsonCreator
   public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
      this.currencyInfo = currencyInfo;
   }
}

来自接受答案的代码转换为java如下:
第一(不是纯粹的不可变的):

@JsonAutoDetect(
   fieldVisibility = Visibility.ANY
)
public final class CurrencyInfo {
   @Nullable
   private String currencyInfo;

   @Nullable
   public final String getCurrencyInfo() {
      return this.currencyInfo;
   }

   public final void setCurrencyInfo(@Nullable String var1) {
      this.currencyInfo = var1;
   }

   public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
      this.currencyInfo = currencyInfo;
   }
}

第二个(可能有还原序列化的问题):

public final class CurrencyInfo {
   @Nullable
   private final String currencyInfo;

   @JsonProperty("currency_info")
   @Nullable
   public final String getCurrencyInfo() {
      return this.currencyInfo;
   }

   public CurrencyInfo(@Nullable String currencyInfo) {
      this.currencyInfo = currencyInfo;
   }
}
quhf5bfb

quhf5bfb3#

您可以添加jackson-module-kotlinhttps://github.com/FasterXML/jackson-module-kotlin)并向Jackson注册Kotlin模块:

val mapper = ObjectMapper().registerKotlinModule()

然后它(和许多其他东西)自动工作。

rt4zxlrg

rt4zxlrg4#

您可以通过调用方法setPropertyNamingStrategy(...)从Jackson库配置ObjectMapper
使用PropertyNamingStrategy.SNAKE_CASE应该可以解决问题
另请参阅此处的其他可用策略:PropertyNamingStrategy

qyuhtwio

qyuhtwio5#

Kotlin不支持将@param和@get注解作为一个注解,所以我们必须编写这样的代码:

data class User(
    @param:JsonProperty("id") @get:JsonProperty("id") val id: Int,
    @param:JsonProperty("name") @get:JsonProperty("name") val name: String
)

在这里你可以告诉JetBrain的家伙支持这个功能,并允许:

data class User(
    @JsonProperty("id") val id: Int,
    @JsonProperty("name") val name: String
)

https://youtrack.jetbrains.com/issue/KT-11005

5m1hhzi4

5m1hhzi46#

此问题已在中解决
https://github.com/FasterXML/jackson-module-kotlin/issues/237
也可以使用

data class SignRequest    
    @param:JsonProperty("estamp_request")
    @get:JsonProperty("estamp_request")
    val eStamp: EstampRequest?
}

data class EstampRequest(
    val tags: Map<String,Int>
)
sbtkgmzw

sbtkgmzw7#

我今天遇到了这个问题,我所做的就是在我的ObjectMapper()中注册KotlinModule()。

@Bean fun objectMapper = ObjectMapper().registreModule(KotlinModule())

上面是一个虚拟的objectMapper,我认为您应该在objectMapper中放置其他配置,如序列化程序等

相关问题