问题描述
我正在尝试使用json4s在Scala应用程序中生成JSON.坦率地说,这是一些示例值,我将这些值汇总到我的Scalatra应用中对其进行测试:
I am attempting to produce JSON in a Scala app using json4s. Fairly straight forward, Here's some sample value I put together to test it in my Scalatra app:
import org.json4s._
import org.json4s.JsonDSL._
object JsonStub {
val getPeople =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))
}
在我的控制器中,我简单地拥有:
In my controller, I simply have:
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
}
}
但是我在浏览器中看到的输出如下:
The output I'm seeing in the browser however, is the following:
{
"_1": "people",
"_2": {
"person_id": 5,
"test_count": 5
}
}
_1
和_2
键来自何处?我原本期望此输出:
Any clue where the _1
and _2
keys are coming from? I was expecting this output instead:
{
"people":{
"person_id": 5,
"test_count": 5
}
}
推荐答案
在输出中看到的是一个反射性序列化的元组,其中包含字段_1
和_2
.这是因为编译器为JsonStub.getPeople
推断的返回类型为Tuple2[String, JObject]
.
What you're seeing in the output is a reflectively serialized tuple, which has fields _1
and _2
. This is because the return type that the compiler has inferred for JsonStub.getPeople
is Tuple2[String, JObject]
.
json4s DSL使用隐式转换将元组之类的值转换为JValue
.但是,如果您不告诉编译器您想要JValue
,它将不会应用转换.
The json4s DSL uses implicit conversions to turn values like the tuple into a JValue
. But, if you don't tell the compiler you wanted a JValue
, it won't apply the conversion.
理想情况下,这将导致编译错误,因为您尝试从不正确的类型中生成JSON.不幸的是,由于您的Web框架假定您要回退到基于反射的序列化,因此这意味着有另一种方法可以将元组转换为JSON,这不是您想要的.
Ideally, this would result in a compile error, because you tried to produce JSON from something that isn't the right type. Unfortunately, because your web framework assumes you want to fall back to reflection-based serialization, it means there is another way to turn the tuple into JSON, which isn't what you wanted.
如果您明确告诉编译器您需要JValue
而不是Tuple2
,则DSL的隐式转换将在正确的位置应用.
If you explicitly tell the compiler that you want a JValue
and not a Tuple2
, the DSL's implicit conversion will be applied in the correct place.
val getPeople: JValue =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))
这篇关于使用json4s在Scala应用中生成json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!