Próbuję produkować JSON w aplikacji Scala przy użyciu json4s. Dość prosto, oto kilka przykładowych wartości, które zebrałem, aby przetestować w mojej aplikacji Scalatra:
import org.json4s._
import org.json4s.JsonDSL._
object JsonStub {
val getPeople =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))
}
W moim kontrolerze po prostu mam:
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
}
}
Dane wyjściowe, które widzę w przeglądarce, są jednak następujące:
{
"_1": "people",
"_2": {
"person_id": 5,
"test_count": 5
}
}
Wszelkie wskazówki, gdzie _1
i _2
klucze pochodzą? Zamiast tego spodziewałem się tego wyniku:
{
"people":{
"person_id": 5,
"test_count": 5
}
}
Odpowiedzi:
5 dla odpowiedzi № 1To, co widzisz w wynikach, to krotka z refleksyjną serią, która ma pola _1
i _2
. Wynika to z tego, że typ zwracany przez kompilator wyprowadził wniosek JsonStub.getPeople
jest Tuple2[String, JObject]
.
DSL json4s używa niejawnych konwersji, aby przekształcić wartości takie jak krotka w a JValue
. Ale jeśli nie powiesz kompilatorowi, że chcesz JValue
, nie zastosuje konwersji.
W idealnym przypadku spowodowałoby to błąd kompilacji,ponieważ próbowałeś wytworzyć JSON z czegoś, co nie jest właściwym typem. Niestety, ponieważ twoja platforma internetowa zakłada, że chcesz wrócić do serializacji opartej na odbiciach, oznacza to, że istnieje inny sposób na przekształcenie krotki w JSON, który nie jest t czego chciałeś.
Jeśli wyraźnie powiesz kompilatorowi, że chcesz JValue
a nie a Tuple2
, niejawna konwersja DSL zostanie zastosowana w odpowiednim miejscu.
val getPeople: JValue =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))