Я переписываю Java Приложение Spring для Kotlin Приложение Spring.
Все отлично работает, кроме API-запроса к openweather.
Для хранения DTO в базе данных есть поле id
вместе с cityId
, полученным из API (там оно называется id
).
По какой-то причине @JsonIgnore не работает для Поле идентификатора DTO.
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 = Лондон, температура = 14,04, feelsLike = 7,05, давление = 1011,0, влажность = 61, облака = ноль, cityId = ноль , время = 1584018901, широта = 51,51, долгота = -0.13)
Я обнаружил похожую проблему на jackson-module-kotlin
странице GitHub , которая оказалась jackson-databind
связанной и решена in 2.9.6 пока я использую 2.10.2