programing

Kotlin + Jackson을 사용하여 JSON을 목록으로 역직렬화하려면 어떻게 해야 합니까?

javajsp 2023. 3. 5. 09:30

Kotlin + Jackson을 사용하여 JSON을 목록으로 역직렬화하려면 어떻게 해야 합니까?

다음 JSON을 역직렬화하기 위한 올바른 구문은 무엇입니까?

[ {
  "id" : "1",
  "name" : "Blues"
}, {
  "id" : "0",
  "name" : "Rock"
} ]

나는 시도했다.

//Works OK
val dtos  = mapper.readValue(json, List::class.java)

원하는 대로:

val dtos : List<GenreDTO>  = mapper.readValue(json, 
    List<GenreDTO>::class.java)

위의 구문은 올바르지 않으며 다음과 같습니다.only classes are allowed on the left hand side of a class literal

주의: @IRUS의 답변도 정확합니다.이 글을 쓰는 동시에 더 자세한 내용을 기입하기 위해 수정하고 있었습니다.

Jackson + Kotlin 모듈을 사용해야 합니다.그렇지 않으면 기본 생성자가 없는 경우 Kotlin 개체로 역직렬화하는 데 다른 문제가 발생합니다.

첫 번째 코드 샘플:

val dtos  = mapper.readValue(json, List::class.java)

의 추정된 유형을 반환하고 있습니다.List<*>더 많은 유형 정보를 지정하지 않았기 때문에 실제로는List<Map<String,Any>>실제로는 정상적으로 동작하고 있지 않지만, 에러는 발생하지 않습니다.안전하지 않습니다. 입력되지 않았습니다.

두 번째 코드는 다음과 같습니다.

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue

val mapper = jacksonObjectMapper()
// ...
val genres: List<GenreDTO> = mapper.readValue(json)

과제 우측에 다른 것은 필요 없습니다.잭슨용 Kotlin 모듈이 제네릭스를 재작성하여TypeReference잭슨을 위해 내부적으로.주의:readValueImport, 필요한 경우 또는.*를 위해com.fasterxml.jackson.module.kotlin모든 기능을 수행하는 확장 기능을 가진 패키지입니다.

약간 다른 방법으로도 기능합니다.

val genres = mapper.readValue<List<GenreDTO>>(json)

Jackson의 확장 기능과 애드온 모듈을 사용하지 않을 이유가 없습니다.이는 작고 기본 생성자를 만들기 위해 후프를 건너뛰거나 주석을 많이 사용해야 하는 다른 문제를 해결합니다.모듈에서는 클래스를 일반 Kotlin으로 할 수 있습니다(옵션).data클래스):

class GenreDTO(val id: Int, val name: String)

표시되는 오류는 다음 식에 대한 것입니다.

List<GenreDTO>::class.java

jvm은 제네릭스를 취급하기 때문에 별도의 클래스는 없습니다.List<GenreDTO>컴파일러가 불만을 제기합니다.마찬가지로 Java에서는 다음이 컴파일되지 않습니다.

List<GenreDTO>.getClass()

다음은 목록을 올바르게 역직렬화하는 샘플입니다.

val value:List<GenreDTO> = mapper.readValue(json, object : TypeReference<List<GenreDTO>>() {})

@Jayson Minard가 지적한 바와 같이 잭슨모듈코틀린을 사용하여 호출을 단순화할 수 있습니다.

val genres: List<GenreDTO> = mapper.readValue(json)
// or
val genres = mapper.readValue<List<GenreDTO>>(json)

이 문제의 원인은 다음과 같습니다.자세한 내용은 참조해 주세요.

다음 코드가 적합합니다.

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.module.kotlin.registerKotlinModule



val json = """[ {
  "id" : "1",
  "name" : "Blues"
}, {
  "id" : "0",
  "name" : "Rock"
} ]"""

data class GenreDTO(val id: Int, val name: String)

val mapper = ObjectMapper().registerKotlinModule()

fun main(args: Array<String>) {
    val obj: List<GenreDTO> = mapper.readValue(json)
    obj.forEach {
        println(it)
    }
}

이 동작은 jackson-kotlin-module 내에 정의되어 있는 확장 함수(재인증된 제네릭을 사용)에 의해 발생합니다.

 public inline fun <reified T: Any> ObjectMapper.readValue(content: String): T = readValue(content, object: TypeReference<T>() {})

@Jayson Minard에게 알려줘서 고마워요.

출력:

GenreDTO(id=1, name=Blues)
GenreDTO(id=0, name=Rock)

언급URL : https://stackoverflow.com/questions/34716697/how-do-i-deserialize-json-into-a-listsometype-with-kotlin-jackson