Convierta ByteArrayOutputStream a json en Kotlin

Estoy intentando crear un recurso para 2 services, 1 en application / x-www-form-urlencoded y string payload y el otro formatting application / json con json body.

Tengo este código:

@POST @Path("/test") fun test(@Context request: ContainerRequest): Response { val baos = ByteArrayOutputStream() request.entityStream.use { it.copyTo(baos) } val ipnRawData = baos.toString() var map : Map<String,Any> map = when (request.headers.getFirst("Content-Type")) { "application/json" -> objectMapper.convertValue(ipnRawData,Map::class.java) as Map<String,Any> "application/x-www-form-urlencoded" -> LinkedHashMap() else -> throw UnsupportedOperationException() } //....handle the map return Response.status(200).build() } 

Pero cuando bash ejecutarlo con la opción json y body: {"name" :"test"} ), aparece un error:

"java.lang.IllegalArgumentException: no se puede build la instancia de java.util.LinkedHashMap: no se puede deserializar el método String-argument / factory de String value ('{" name ":" test "}')"

Gracias por cualquier ayuda, Yoel

Debería usar mapper.readValue para deserializar JSON en un object.

Usando raw Jackson sin el module Jackson-Kotlin :

 val map: Map<String, String> = JSON.readValue("""{"name" :"test"}""", object : TypeReference<Map<String, String>>() {}) 

Esto pasa en una expresión de object con superclass TypeReference especifica el tipo que desea crear con generics completos aún intactos (su método sufre de borrado de tipo).

En cambio, si está utilizando el module Jackson-Kotlin , solo necesita:

 val map: Map<String, String> = JSON.readValue("""{"name" :"test"}""") 

Dado que tiene funciones de ayuda / extensión para ocultar algunas de las cosas más feas como la creación de TypeReference .

Siempre debe usar el module Jackson-Kotlin con el código Kotlin para que pueda instanciar cualquier tipo de object Kotlin incluyendo classs de datos que tengan todos los parameters val y sin constructores pnetworkingeterminados, que entienda nulability, y también que maneje valores pnetworkingeterminados para parameters de constructor. Un simple ejemplo independiente:

 import com.fasterxml.jackson.module.kotlin.* val JSON = jacksonObjectMapper() // creates ObjectMapper() and adds Kotlin module in one step val map: Map<String, String> = JSON.readValue("""{"name" :"test"}""") 

Observe la import .* que capte todas las funciones de extensión; de lo contrario, debe importar explícitamente: com.fasterxml.jackson.module.kotlin.readValue

O en su caso, el código modificado sería:

 import com.fasterxml.jackson.module.kotlin.readValue val objectMapper = jacksonObjectMappe() // instead of ObjectMapper() ... @POST @Path("/test") fun test(@Context request: ContainerRequest): Response { val bodyAsString = request.entityStream.buffenetworkingReader().readText() val map: Map<String, Any> = when (request.headers.getFirst("Content-Type")) { "application/json" -> objectMapper.readValue(bodyAsString) "application/x-www-form-urlencoded" -> LinkedHashMap() else -> throw UnsupportedOperationException() } //....handle the map return Response.status(200).build() } 

El código también se ha limpiado un poco para eliminar el uso de var y leer la secuencia de entidades de una manera más amigable para Kotlin.

También tenga en count que el encabezado Content-Type puede ser más complicado, también podría contener encoding, como por ejemplo:

 Content-type: application/json; charset=utf-8 

Por lo tanto, es posible que desee una function de utilidad que compruebe si el encabezado es "igual a application/json o comienza con application/json; " en lugar de solo una comprobación de igualdad.

Por último, puede pasar el request.entityStream directamente a objectMapper.readValue y nunca copyrlo en una cadena. Hay varias sobrecargas para readValue que son útiles para este tipo de inputs.

  • Establecer una extensión de kotlin
  • ¿Hay alguna manera de build un HashSet con function de initialization en Kotlin?
  • NullPointerException en android.support.v4.app.NotificationCompatBase $ Action.getIcon ()
  • Gradle no puede encontrar testings
  • Convierta variables estáticas de Java a Kotlin
  • ¿Cómo puedo get una request web actual usando Vert.x Web?
  • Diseño de expresiones regulares multilínea
  • ¿Referencia fuera de la class sellada en Kotlin?
  • KMango: colección de actualización con col.updateOne / col.updateMany
  • Problema con Kotlin después de que Android Studio se actualizó a 0.6
  • Error de reference sin resolver en copyOfRange