

プログラミン初学者です。  
タイトルの通りkotlinとJacksonを用いてLocalTimeなどのデータをシリアライズしたのですが  
うまく実装できません。ご回答お願いします。

書いたコード

[code]

    JacksonPractice.kt
    @RestController
    @RequestMapping("json")
    class JacksonPractice {
    
        @PostMapping(
                value=[""],
                consumes = ["application/json"]
        )
        fun postJsonData(@RequestBody json: String) {
            println("called getJsonData")
            println("----- json data -----")
            println(json)
            println("")
            val mapper = ObjectMapper()
            mapper.registerModule(JavaTimeModule())
            val jsonData = mapper.readValue<JsonData>(json)
            println("----- json serialize -----")
            println(jsonData)
        }
    }
    
[/code]

JsonDataModel.kt(データクラス)

[code]

    package practice.kotlinjackson.model
    
    import com.fasterxml.jackson.annotation.JsonFormat
    import com.fasterxml.jackson.databind.annotation.JsonDeserialize
    import com.fasterxml.jackson.databind.annotation.JsonSerialize
    import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
    import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer
    import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer
    import java.time.LocalDateTime
    import java.time.LocalTime
    
    data class JsonData(
            val id: Int,
            val name: String,
            @JsonSerialize(using = ToStringSerializer::class)
            @JsonDeserialize(using = LocalDateTimeDeserializer::class)
            val date : LocalDateTime,
            @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss")
            val time: LocalTime,
            val jsonDataDetail: JsonDataDetail
    )
    
    data class JsonDataDetail(
            val detail: String
    )
    
[/code]

guild.gradle.kts

[code]

    import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
    
    plugins {
        id("org.springframework.boot") version "2.5.3"
        id("io.spring.dependency-management") version "1.0.11.RELEASE"
        kotlin("jvm") version "1.5.21"
        kotlin("plugin.spring") version "1.5.21"
    }
    
    group = "practice.kotlin-jackson"
    version = "0.0.1-SNAPSHOT"
    java.sourceCompatibility = JavaVersion.VERSION_11
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-web")
        implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
        implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.5")
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
        testImplementation("org.springframework.boot:spring-boot-starter-test")
    }
    
    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "11"
        }
    }
    
    tasks.withType<Test> {
        useJUnitPlatform()
    }
    
[/code]

リクエストは下記のjsonデータをpostmanからリクエストしています

[code]

    {
        "id": 10,
        "name": "kotlin jackson",
        "date": "2017-11-13T06:40:00Z",
        "time": "10:00:00",
        "jsonDataDetail": {
            "detail": "data detail"
        }
    }
    
[/code]


CC BY-SA 4.0
2021-08-02T15:05:32.947
80549
2023-02-09T03:04:55.713
47565
question
json spring spring-boot kotlin jackson
kotlinとJacksonを用いてjsonデータをLocalTimeにシリアライズしたいのですが、実装できません


Kotlinの data class を直接扱うためには `KotlinModule` の登録も必要のようです:

[code]

        fun postJsonData(@RequestBody json: String) {
            println("called getJsonData")
            println("----- json data -----")
            println(json)
            println("")
            val mapper = ObjectMapper().registerModules(KotlinModule(), JavaTimeModule())
            val jsonData = mapper.readValue<JsonData>(json)
            println("----- json serialize -----")
            println(jsonData)
        }
    
[/code]

  * <https://github.com/FasterXML/jackson-module-kotlin>
  * <https://www.baeldung.com/kotlin/jackson-kotlin>

* * *

Spring Bootにデフォルトで組み込まれているメッセージコンバータに任せるのも一般的でしょう:

[code]

        fun postJsonData(@RequestBody jsonData: JsonData) {
            println("----- json serialize -----")
            println(jsonData)
        }
    
[/code]

  * <https://docs.spring.io/spring-framework/docs/5.3.9/reference/html/web.html#mvc-ann-requestbody>
  * <https://docs.spring.io/spring-boot/docs/2.5.3/reference/htmlsingle/#howto.spring-mvc.customize-jackson-objectmapper>


CC BY-SA 4.0
2021-08-02T19:17:08.150
80551
2021-08-02T19:34:35.610
2021-08-02T19:34:35.610
2808
2808
80549
answer


備忘録の為に最終的に解決したコードを記載します  
<https://github.com/ShutoKeisuke/kotlin-jackson-practice>

Controller

[code]

    @RestController
    @RequestMapping("json")
    class JacksonPractice {
    
        @PostMapping(
                value=[""],
                consumes = ["application/json"]
        )
        fun postJsonData(@RequestBody json: String) {
            println("called getJsonData")
            println("----- json data -----")
            println(json)
            println("")
            val mapper = ObjectMapper().registerKotlinModule()
            mapper.registerModule(JavaTimeModule())
            val jsonData = mapper.readValue<JsonData>(json)
            println("----- json serialize -----")
            println(jsonData)
        }
    
        @PostMapping(value = ["converter"])
        fun postMessageConverter(@RequestBody jsonData: JsonData) {
            println("----- json serialize -----")
            println(jsonData)
        }
    }
    
[/code]

Data Class

[code]

    import java.time.LocalDateTime
    import java.time.LocalTime
    
    data class JsonData(
            val id: Int,
            val name: String,
    //        @JsonSerialize(using = ToStringSerializer::class)
    //        @JsonDeserialize(using = LocalDateTimeDeserializer::class)
            val date : LocalDateTime,
    //        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm")
            val time: LocalTime,
            val jsonDataDetail: JsonDataDetail
    )
    
    data class JsonDataDetail(
            val detail: String
    )
    
[/code]

build.gradle.kts

[code]

    import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
    
    plugins {
        id("org.springframework.boot") version "2.5.3"
        id("io.spring.dependency-management") version "1.0.11.RELEASE"
        kotlin("jvm") version "1.5.21"
        kotlin("plugin.spring") version "1.5.21"
    }
    
    group = "practice.kotlin-jackson"
    version = "0.0.1-SNAPSHOT"
    java.sourceCompatibility = JavaVersion.VERSION_11
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-web")
        implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
        implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.5")
        // ↓たぶんいらない
        implementation ("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.+")
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
        testImplementation("org.springframework.boot:spring-boot-starter-test")
    }
    
    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "11"
        }
    }
    
    tasks.withType<Test> {
        useJUnitPlatform()
    }
    
    
[/code]

Json ※Postmanからリクエストして確認

[code]

    {
        "id": 10,
        "name": "kotlin jackson",
        "date": "2017-11-13T06:40:00Z",
        "time": "10:00",
        "jsonDataDetail": {
            "detail": "data detail"
        }
    }
    
[/code]


CC BY-SA 4.0
2021-08-03T12:19:10.843
80567
2021-08-03T12:24:50.190
2021-08-03T12:24:50.190
47565
47565
80549
answer