Java 对 kotlin 数据类使用 Jackson @JsonProperty 注释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47982148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:44:20  来源:igfitidea点击:

Usage of Hymanson @JsonProperty annotation for kotlin data classes

javajsonHymansonkotlindeserialization

提问by Mike

kotlin 1.2.10 Hymanson-module-kotlin:2.9.0

科特林 1.2.10 Hyman逊模块科特林:2.9.0

I have the following data class in kotlin:

我在 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?
)

When I try to deserialize this data class I get the following:

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

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

As you can see, the last two options were deserialized incorrectly. This issue could be solved by adding directly annotation to getter @get:JsonProperty. However, according to Hymanson docs @JsonProperty should be assigned to getters/setters/fields

如您所见,最后两个选项反序列化不正确。这个问题可以通过在 getter @get:JsonProperty 中直接添加注解来解决。但是,根据 Hymanson docs @JsonProperty 应该分配给 getter/setter/fields

So, I want to ask is there a reliable way to annotate property for Hymanson in kotlin to have correct serialization/deserialization (moreover all my data classes are autogenerated, so it would be hard to create some two/three lines annotations, separately for getter and setter)

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

Otherwise, could this issue be resolved by some Hymanson settings?

否则,这个问题可以通过一些Hyman逊设置来解决吗?

According to answers below, the following works for me

根据下面的答案,以下对我有用

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)

采纳答案by SimY4

@JsonPropertyannotations in your code are all put on private fields within your data class and by default Hymanson doesn't scan private fields for annotations. You have to instruct it to do otherwise by putting @JsonAutoDetectannotation:

@JsonProperty代码中的注释都放在数据类中的私有字段上,默认情况下,Hymanson 不会扫描私有字段以获取注释。您必须通过添加@JsonAutoDetect注释来指示它做其他事情:

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

or alternatively you can move your annotations on accessor methods:

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

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

回答by Prim

You can configure the ObjectMapper from the Hymanson library by calling the method setPropertyNamingStrategy(...)

您可以通过调用方法从 Hymanson 库配置 ObjectMapper setPropertyNamingStrategy(...)

Using PropertyNamingStrategy.SNAKE_CASEshould resolve your problem

使用PropertyNamingStrategy.SNAKE_CASE应该可以解决您的问题

See also the other available strategies here : PropertyNamingStrategy

另请参阅此处的其他可用策略:PropertyNamingStrategy

回答by GameScripting

You can add the Hymanson-module-kotlin(https://github.com/FasterXML/Hymanson-module-kotlin) and register the kotlin module with Hymanson:

您可以添加Hymanson-module-kotlin( https://github.com/FasterXML/Hymanson-module-kotlin) 并向 Hymanson 注册 kotlin 模块:

val mapper = ObjectMapper().registerModule(KotlinModule())

Then it (and many other things) works automagically.

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

回答by Maksim Turaev

You can do something like this:

你可以这样做:

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

code above translates to java as:

上面的代码转换为 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;
   }
}


code from accepted answer translates to java as following:

接受的答案中的代码转换为 java 如下:

First (is not pure immutable):

首先(不是纯粹的不可变):

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

Second (probably has problems with deserialization):

第二(可能有反序列化问题):

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

回答by Ivan Rodrigues

I faced this problem today and what I did was register KotlinModule() in my ObjectMapper(). Bellows follow an example.

我今天遇到了这个问题,我所做的是在我的 ObjectMapper() 中注册 KotlinModule()。波纹管遵循一个例子。

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

Above it's a dummy objectMapper, I believe that you should put other configurations in your objectMapper like serializers and so on

上面是一个虚拟的 objectMapper,我相信你应该在你的 objectMapper 中放置其他配置,比如序列化器等等