Estou tentando produzir JSON em um aplicativo Scala usando json4s. Bastante direto, aqui está um exemplo de valor que reuni para testá-lo no meu aplicativo Scalatra:
import org.json4s._
import org.json4s.JsonDSL._
object JsonStub {
val getPeople =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))
}
No meu controlador, eu simplesmente tenho:
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.{DefaultFormats, Formats}
class FooController(mongoDb: MongoClient)(implicit val swagger: Swagger) extends ApiStack with NativeJsonSupport with SwaggerSupport {
get ("/people", operation(getPeople)) {
JsonStub.getPeople
}
}
A saída que estou vendo no navegador, porém, é a seguinte:
{
"_1": "people",
"_2": {
"person_id": 5,
"test_count": 5
}
}
Qualquer pista onde o _1
e _2
chaves estão vindo? Eu estava esperando esta saída:
{
"people":{
"person_id": 5,
"test_count": 5
}
}
Respostas:
5 para resposta № 1O que você está vendo na saída é uma tupla serialmente refletiva, que possui campos _1
e _2
. Isso ocorre porque o tipo de retorno que o compilador inferiu para JsonStub.getPeople
é Tuple2[String, JObject]
.
O DSL do json4s usa conversões implícitas para transformar valores como a tupla em um JValue
. Mas, se você não disser ao compilador que queria JValue
, não aplicará a conversão.
Idealmente, isso resultaria em um erro de compilação,porque você tentou produzir JSON a partir de algo que não é o tipo certo. Infelizmente, como sua estrutura da web pressupõe que você queira voltar à serialização baseada em reflexão, isso significa que há outra maneira de transformar a tupla em JSON, que não é " o que você queria.
Se você disser explicitamente ao compilador que deseja uma JValue
e não um Tuple2
, a conversão implícita da DSL será aplicada no local correto.
val getPeople: JValue =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))