1.29 Jackson @JsonProperty批注在Kotlin数据类中的用法| Java Debug 笔记

778 阅读2分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

Debug 笔记 <Jackson @JsonProperty批注在Kotlin数据类中的用法>

提问

kotlin 1.2.10 jackson-module-kotlin:2.9.0

我在kotlin中具有以下数据类:

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,可以解决此问题。

但是,根据文档,@ JsonProperty应该分配给getters / setters / fields

因此,我想问问是否有一种可靠的方法来为kotlin中的jackson注释属性以具有正确的序列化/反序列化(而且我的所有数据类都是自动生成的,因此很难分别为getter创建一些两行或三行注释和二传手)

否则,可以通过某些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)

回答一

@JsonProperty代码中的注释都放在数据类的私有字段中,默认情况下,Jackson不会扫描私有字段中的注释。您必须通过添加@JsonAutoDetect注释来指示它执行其他操作:

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

或者,您也可以在访问器方法上移动注释:

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

回答二

您可以执行以下操作:

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;
   }
}

回答三

您可以添加jackson-module-kotlingithub.com/FasterXML/j…

并向jackson注册kotlin模块: val mapper = ObjectMapper().registerModule(KotlinModule())

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

文章翻译自Stack Overflow :stackoverflow.com/questions/4…