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.

  • KDoc: insert fragment de código
  • ¿El DAO de Kotlin debería ser opcional o nulo?
  • Variable opcional de class de datos de Kotlin
  • Error: ejecución fallida para la tarea ': app: kaptDemoTestingDebugKotlin'
  • Kotlin Spek - ¿Cómo generar XML con informe de testings?
  • Fan-out / fan-in - canal de resultado de cierre
  • Defina múltiples variables a la vez en Kotlin (p. Ej., Java: String x, y, z;)
  • No se puede escribir el constructor principal para la class Activity en Kotlin en Android
  • ¿Dónde están los files .class?
  • Kotlin recibe el tipo de cadena
  • ¿Cómo creo una variable de function con una cantidad variable de arguments?