Cómo usar jackson para deserializar las collections de Kotlin

Código de muestra lo que quiero:

data class D(val a: String, val b: Int) val jsonStr = """[{"a": "value1", "b": 1}, {"a": "value2", "b":"2}]""" // what I need val listOfD: List<D> = jacksonObjectMapper().whatMethodAndParameter? 

Con las versiones actuales del Módulo Jackson Kotlin, si importa el package de module completo o la function de extensión específica, tendrá todos los methods de extensión disponibles. Como:

 import com.fasterxml.jackson.module.kotlin.* val JSON = jacksonObjectMapper() // keep around and re-use val myList: List<String> = JSON.readValue("""["a","b","c"]""") 

Por lo tanto, el Módulo Jackson para Kotlin deducirá el tipo correcto y no necesita una instancia de TypeReference .

por lo que su caso (ligeramente renombrado y corregido la class de datos, y JSON):

 import com.fasterxml.jackson.module.kotlin.readValue data class MyData(val a: String, val b: Int) val JSON = jacksonObjectMapper() val jsonStr = """[{"a": "value1", "b": 1}, {"a": "value2", "b": 2}]""" val myList: List<MyData> = JSON.readValue(jsonStr) 

También puedes usar el formulario:

 val myList = JSON.readValue<List<MyData>>(jsonStr) 

Sin la import, tendrá un error porque no se encuentra la function de extensión.

TL; DR

Con Jackson 2.6.3-2 haga lo que @ jason-minard aconseja y simplemente use:

 import com.fasterxml.jackson.module.kotlin.readValue val listOfD: List<D> = jacksonMapper.readValue(jsonStr) 

Detalles

No hay nada especial acerca de Kotlin wrt en deserializar collections , aunque necesitará el module kotlin jackson para deserializar classs de datos sin annotations.

A saber, requerirá información completa del tipo reificado en su caso para poder seguir el parámetro genérico de la list ( D ); de lo contrario (por ejemplo, si usa readValue(jsonStr, List::class.java) ) Jackson solo lo verá como un tipo borrado (es decir, List ) (como lo hace explícito Kotlin) y lo deserializará a List<Map<String, String>> , sin saber que tiene que build D s. Esto se TypeReference utilizando una subclass anónima de TypeReference en Java para que Jackson pueda acceder al tipo completo reificado para deserializar en time de ejecución.

Traduciendo el código de Jackson Java literalmente a Kotlin, lo siguiente logra lo que quieres (y como comentó @eski, ten en count que el JSON en tu ejemplo no es válido):

 val jacksonMapper = ObjectMapper().registerModule(KotlinModule()) val jsonStr = """[{"a": "value1", "b": 1}, {"a": "value2", "b":2}]""" val listOfD: List<D> = jacksonMapper.readValue(jsonStr, object : TypeReference<List<D>>(){}) assertEquals(listOf(D("value1", 1), D("value2", 2)), listOfD) 

Sin embargo, esto es un poco detallado y feo, por lo que podría ocultarlo en una function Kotlin (extensión) (especialmente si planea usarla varias veces):

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

que le permitiría entonces simplemente llamar:

 val listOfD: List<D> = jacksonMapper.readValue(jsonStr) 

Y esto es lo que está incluido en el module 2.6.3-2 jackson Kotlin.

  • Cómo establecer pivotes dynamics para girar la animation
  • Error al configurar el reino con kotlin
  • Cómo escribir una corutina recursiva en kotlin
  • Habitación Android + Patrón Kotlin
  • Cómo detener el service de notificación en Android Oreo
  • ¿Cómo instalar y configurar Kara Web Framework?
  • Referencia no resuelta de Kotlin en time de compilation
  • ¿Qué significa una firma de function de Kotlin con T. ()?
  • NoSuchMethodError utilizando Kotlin con el nuevo data binding de Android
  • Error: ejecución fallida para la tarea ': app: compileDebugKotlinAfterJava'
  • ¿Cómo establecer la pestaña BottomNavigationView pnetworkingeterminada en Kotlin?