source

kotlin 데이터 클래스에 대한 Jackson@JsonProperty 주석 사용

myloves 2023. 3. 29. 22:04

kotlin 데이터 클래스에 대한 Jackson@JsonProperty 주석 사용

kotlin 1.2.10 잭슨-sysloglin: 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에 직접 주석을 추가하여 해결할 수 있습니다.Json Property.그러나 잭슨 문서에 따르면 @JsonProperty는 getters/setters/fields에 할당해야 합니다.

따라서 kotlin의 잭슨이 올바른 시리얼화/디시리얼라이제이션(모든 데이터 클래스가 자동 생성되므로 getter와 setter용으로 각각 2~3줄의 주석을 작성하기가 어렵습니다)에 대한 신뢰할 수 있는 방법이 있는지 묻고 싶습니다.

그렇지 않으면 잭슨 설정으로 이 문제가 해결될 수 있습니까?

아래 답변에 따르면 다음 사항이 좋습니다.

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코드의 주석은 모두 데이터 클래스 내의 개인 필드에 배치되며 기본적으로 잭슨은 개인 필드에서 주석을 검색하지 않습니다.다른 방법으로 하도록 지시해야 합니다.@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;
   }
}

code from accepted answer는 다음과 같이 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-kotlin(https://github.com/FasterXML/jackson-module-kotlin)에서 코틀린 모듈을 잭슨에 등록합니다.

val mapper = ObjectMapper().registerKotlinModule()

그 후, 그 외의 많은 것이 자동적으로 동작합니다.

잭슨 라이브러리에서 오브젝트 맵퍼를 설정하려면 메서드를 호출합니다.setPropertyNamingStrategy(...)

사용.PropertyNamingStrategy.SNAKE_CASE문제가 해결됩니다.

Property Naming Strategy 를 참조해 주세요.

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

이 문제는 에서 해결됩니다.

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>
)

저는 오늘 이 문제에 직면했고, 제가 한 일은 Kotlin Module()을 제 Object Mapper()에 등록한 것입니다.풀무는 예를 따른다.

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

그 위에는 더미 오브젝트 맵퍼가 있습니다.오브젝트 맵퍼에는 시리얼라이저 등의 다른 설정을 넣어야 한다고 생각합니다.

언급URL : https://stackoverflow.com/questions/47982148/usage-of-jackson-jsonproperty-annotation-for-kotlin-data-classes