将ByteArrayOutputStream转换为Kotlin中的json

我试图创建一个2服务的资源,1在application / x-www-form-urlencoded和字符串有效载荷和其他应用程序/ json格式与json正文。

我有这个代码:

@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 map = when (request.headers.getFirst("Content-Type")) { "application/json" -> objectMapper.convertValue(ipnRawData,Map::class.java) as Map "application/x-www-form-urlencoded" -> LinkedHashMap() else -> throw UnsupportedOperationException() } //....handle the map return Response.status(200).build() } 

但是,当我尝试运行它与json选项,和身体: {"name" :"test"} ),我得到一个错误:

“java.lang.IllegalArgumentException:无法构造java.util.LinkedHashMap的实例:no String-argument构造函数/工厂方法从字符串反序列化value('{”name“:”test“}’)”

谢谢你的帮助,Yoel

您应该使用mapper.readValue将JSON反序列化为一个对象。

使用没有 Jackson-Kotlin模块的原始Jackson:

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

这传入一个超类TypeReference的对象expression式 ,指定你想创建的types,完整的generics仍然完好(你的方法遭受types擦除)。

相反,如果您使用的是Jackson-Kotlin模块 ,则只需要:

 val map: Map = JSON.readValue("""{"name" :"test"}""") 

因为它有助手/扩展function来隐藏一些丑陋的东西,如typesTypeReference创建。

您应该始终使用带有Kotlin代码的Jackson-Kotlin模块 ,以便您可以实例化任何types的Kotlin对象,包括具有所有val参数且没有默认构造函数的数据类,让它了解可空性,并处理构造函数参数的默认值。 一个简单的独立的例子:

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

请注意导入.*以便它获取所有扩展函数,否则您需要显式导入: com.fasterxml.jackson.module.kotlin.readValue

或者在你的情况下,修改后的代码将是:

 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.bufferedReader().readText() val map: Map = 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() } 

该代码也被清理了一点,以删除var的使用,并以更多的Kotlin友好的方式阅读实体流。

另外请注意, Content-Type头可能更复杂,也可能包含编码,例如:

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

因此,您可能需要一个实用程序函数来检查头是否“等于application/json或者以application/json开头”,而不是仅仅进行相等性检查。

最后,您可以直接将request.entityStream传递给objectMapper.readValueobjectMapper.readValue其复制到字符串中。 对于这些types的输入, readValue有各种重载。