Вы должны использовать mapper.readValue
для десериализации JSON в объект.
Использования сырой Джексон безJackson-Kotlin module:
val map: Map<String, String> = JSON.readValue("""{"name" :"test"}""",
object : TypeReference<Map<String, String>>() {})
Это проходит в object expression с суперклассом TypeReference
указав тип, который Вы желаете, чтобы создать с полными дженерик еще интактными (вы метод страдает от типа стирание).
Вместо этого, если вы используете Jackson-Kotlin module вам нужно всего лишь:
val map: Map<String, String> = JSON.readValue("""{"name" :"test"}""")
Поскольку она имеет функции помощника/расширения, чтобы скрыть некоторые уродливее вещи, как TypeReference
создания.
Вы должны всегда использовать Jackson-Kotlin module с Котлин кодом, так что вы можете создать экземпляр любого типа объекта Котлин, включая классы данных, которые имеют все val
параметры и конструкторы по умолчанию нет, есть это понять допустимость пустых, а также иметь дело со значениями по умолчанию для параметры конструктора. Простой автономный пример:
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"}""")
Обратите внимание на импорт .*
так, что он улавливает все функции расширения в противном случае вам нужно явно импорт: 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<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()
}
код также был очищен немного, чтобы удалить использование var
и прочитать поток сущностей в более Котлин friendl y way.
Также обратите внимание, что заголовок Content-Type
может быть более сложным, он может содержать кодирование, а также такие, как:
Content-type: application/json; charset=utf-8
Таким образом, вы можете служебную функцию, которая проверяет, если заголовок «равен application/json
или начинается с application/json;
"вместо проверки равенства.
Наконец-то вы можете передать request.entityStream
прямо на номер objectMapper.readValue
и никогда не копировать его в строку.Существуют различные перегрузки для readValue
, которые полезны для этих типов входов.
Спасибо за подробный ответ и полезные советы! – Joel