【问题标题】:Jackson JsonIgnore does not work in kotlinJackson JsonIgnore 在 kotlin 中不起作用
【发布时间】:2020-03-12 19:19:29
【问题描述】:

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

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

为了将 DTO 存储在数据库中,有 id 字段以及从 API 检索到的 cityId(在那里称为 id)。

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

build.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, feelLike=7.05, pressure=1011.0,湿度=61, clouds=null, cityId=null , 时间=1584018901, 纬度=51.51, 经度=-0.13)

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

【问题讨论】:

    标签: java json spring kotlin jackson


    【解决方案1】:

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

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

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

    但是任何注释适用于什么?

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

    详细信息请参见Kotlin docs

    【讨论】:

    • 感谢您的回答,但不幸的是它不起作用。与 .@get:JsonProperty / .@set:JsonProperty / .@field:JsonProperty / .@get:JsonProperty .@set:JsonProperty .@JsonProperty 中的任何一个一起使用。 id 转到 id(
    • 我在 val 上使用了 get(),它按预期工作。 ?
    【解决方案2】:

    我没有找到解决办法,但是

        @JsonProperty("_id")
        override var id: Long? = null,
    

    它按预期工作。

    【讨论】:

      猜你喜欢
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 2011-02-26
      • 2013-08-11
      • 2017-03-21
      • 1970-01-01
      相关资源
      最近更新 更多