【问题标题】:Producing json in a Scala app using json4s使用 json4s 在 Scala 应用程序中生成 json
【发布时间】:2013-07-06 05:59:08
【问题描述】:

我正在尝试使用 json4s 在 Scala 应用程序中生成 JSON。相当直截了当,以下是我汇总的一些示例值,用于在我的 Scalatra 应用程序中对其进行测试:

import org.json4s._
import org.json4s.JsonDSL._


object JsonStub {
    val getPeople = 
        ("people" ->
            ("person_id" -> 5) ~
            ("test_count" -> 5))

}

在我的控制器中,我只有:

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
    }   

}

然而,我在浏览器中看到的输出如下:

{
  "_1": "people",
  "_2": {
    "person_id": 5,
    "test_count": 5
  }
}

知道_1_2 键的来源吗?我期待的是这个输出:

{
  "people":{
    "person_id": 5,
    "test_count": 5
  }
}

【问题讨论】:

    标签: json scala scalatra json4s


    【解决方案1】:

    您在输出中看到的是一个反射序列化元组,其中包含字段_1_2。这是因为编译器为JsonStub.getPeople 推断的返回类型是Tuple2[String, JObject]

    json4s DSL 使用隐式转换将像元组这样的值转换为JValue。但是,如果你不告诉编译器你想要一个JValue,它就不会应用转换。

    理想情况下,这会导致编译错误,因为您试图从不正确的类型生成 JSON。不幸的是,因为您的 Web 框架假定您想回退到基于反射的序列化,这意味着还有另一种方法可以将元组转换为 JSON,这不是您想要的。

    如果您明确告诉编译器您需要 JValue 而不是 Tuple2,则 DSL 的隐式转换将应用到正确的位置。

    val getPeople: JValue = 
        ("people" ->
            ("person_id" -> 5) ~
            ("test_count" -> 5))
    

    【讨论】:

    • 做到了,本,非常感谢。关于如何在不先在此处发布的情况下解决此问题的任何提示? :-) 可能还有一种方法可以在这里将我的所有值默认为 JValue,只是不完全确定如何。
    • 如果你想要类型安全的开发,我的专业建议是不要使用 Scalatra。除此之外,为 API 的公共成员指定返回类型总是一个好主意,尤其是在依赖隐式时。
    • 有没有办法告诉 json4s 明确地进行转换?我遇到了同样的事情,我不想用JValues 乱扔我的模型类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    相关资源
    最近更新 更多