gpt4 book ai didi

java - Jackson JsonIgnore 在 kotlin 中不起作用

转载 作者:行者123 更新时间:2023-12-01 17:59:34 24 4
gpt4 key购买 nike

我正在将 Java Spring 应用程序重写为 Kotlin Spring 应用程序。

除了对 openweather 的 API 请求之外,一切正常。

要将 DTO 存储在数据库中,需要有 id 字段以及从 API 检索的 cityId(此处称为 id)。

出于某种原因,@JsonIgnore 不适用于 DTO id 字段。

构建.gradle

// plugins

id 'org.springframework.boot' version '2.2.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
id 'war'
id 'maven'
id 'org.jetbrains.kotlin.jvm' version '1.3.70'
id "org.jetbrains.kotlin.plugin.jpa" version "1.3.70"
id "org.jetbrains.kotlin.plugin.noarg" version "1.3.70"
id "org.jetbrains.kotlin.plugin.spring" version "1.3.70"
id "org.jetbrains.kotlin.plugin.allopen" version "1.3.70"


// dependencies

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-mail:2.2.4.RELEASE'
implementation 'org.springframework.security:spring-security-test'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlin:kotlin-reflect"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2"

OpenWeather 使用下一个 JSON 进行响应(省略了一些字段):

{
"coord":{
"lon":-0.13,
"lat":51.51
},
"main":{
"temp":14.04,
"feels_like":7.05,
"pressure":1011,
"humidity":61
},
"dt":1584018901,
"id":2643743, <- cityId in DTO class
"name":"London",
...
}

DTO 类:


import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty

@JsonIgnoreProperties(ignoreUnknown = true)
data class OpenWeatherApiDto(
@JsonIgnore
override var id: Long? = null,
...
override var cityId: Int? = null,
...
) : AbstractWeatherSampleDto() {
...
@JsonProperty("id")
private fun unpackId(idObj: Int?) {
cityId = idObj
?: throw ApiFieldNotFoundException("id")
}
...
}

测试失败

@Test
fun createFromFile() {
val mapper = jacksonObjectMapper()
Files.lines(Paths.get("src/test/resources/data/OWApi.json")).use { s ->
val json: String = s.collect(Collectors.joining())
val ws: OpenWeatherApiDto = mapper.readValue(json)
println(ws)
assertThat(ws)
.isNotNull
.extracting("cityId").isEqualTo(2643743)
}
}

失败消息是:

[Extracted: cityId] 
Expecting:
<null>
to be equal to:
<2643743>
but was not.

实际对象是:

OpenWeatherApiDto(id=2643743, cityName=London, temperature=14.04, feelsLike=7.05, pressure=1011.0, humidity=61, clouds=null, cityId=null, time=1584018901, latitude=51.51, longitude=-0.13)

我在 jackson-module-kotlin GitHub page 上发现了类似的问题恰好是 Jackson-databind relatedresolved2.9.6 中,而我使用 2.10.2

最佳答案

我还没有尝试过您正在使用的确切版本,但我怀疑如果您替换@JsonIgnore,它会起作用。与 @get:JsonIgnore

这是将 Java 转换为 Kotlin 时常见的问题之一。在 Java 中,通常使用私有(private)字段和 getter 方法(如果可变,则还可以使用 setter)来实现属性。您还可以包含一个构造函数参数来初始化它。这最多有四个独立的代码位,全部与同一属性相关 - 并且每个代码位都可以有自己的注释。

但是,在 Kotlin 中,您可以通过一段代码获得所有这些。 (任何非私有(private)属性都会为您提供一个私有(private)字段和一个 getter 方法;如果它是 var,您还会获得一个 setter;如果它在主构造函数中,那么您还会获得一个构造函数参数。)这更加简洁!

但是注释适用于什么?

默认情况下,它们应用于构造函数参数 - 或者,如果属性是在类主体中定义的,则应用于属性本身(仅对 Kotlin 可见)。因此,如果您希望它们应用于字段,或者 getter 或 setter,您需要明确指定,例如@field:JsonIgnore@get:JsonIgnore .

完整详细信息位于 Kotlin docs .

关于java - Jackson JsonIgnore 在 kotlin 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60660605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com