【问题标题】:Parse any JSON to JValue without specifying a case class在不指定案例类的情况下将任何 JSON 解析为 JValue
【发布时间】:2016-06-06 15:20:34
【问题描述】:

我试图解释得更好。

我正在从一个 json 字符串解析一个 json 文件,例如:

[
 {
   "album": "The White Stripes",
   "year": 1999,
   "US_peak_chart_post": 55
 },
 {
   "album": "De Stijl",
   "year": 2000,
   "US_peak_chart_post": 66
 }
]

Seq[Album]

import org.json4s._
import org.json4s.jackson.JsonMethods._
import scala.util.{Failure, Success, Try}

object AlbumsHandler{
    implicit val formats = DefaultFormats

    def extractAlbumsFromJsonFile(json: String): Seq[Album] = {

      val jValues: Try[JValue] = Try(parse(json))
      val albums: Seq[Album] = jValues.map(
        value => value.extract[Seq[Album]]
      ).getOrElse(Seq())

      albums
    }
}

通过提供Albumcase class 作为“蓝图”:

case class Album(album: String, year: Int, US_peak_chart_post: Int)

有没有办法做我已经在做的事情,从我的 JSON 中自动提取 Seq[Album],而无需将 case class 指定为蓝图?

非常感谢

【问题讨论】:

    标签: json scala json4s


    【解决方案1】:

    嗯,任何 JSON 对象都可以提取到 Map 中,任何 JSON 数组都可以提取到 Seq 中。但是,使用Map[String, Any] 并不太方便,没有什么比指定一个案例类来提取类型安全结构更简单的了。

    import org.json4s._
    import org.json4s.jackson.JsonMethods._
    
    implicit val formats = DefaultFormats
    
    val json = """[
                 | {
                 |   "album": "The White Stripes",
                 |   "year": 1999,
                 |   "US_peak_chart_post": 55
                 | },
                 | {
                 |   "album": "De Stijl",
                 |   "year": 2000,
                 |   "US_peak_chart_post": 66
                 | }
                 |]""".stripMargin
    
    val map = parse(json).extract[Seq[Map[String, Any]]]
    // map: Seq[Map[String,Any]] = List(Map(album -> The White Stripes, year -> 1999, US_peak_chart_post -> 55), Map(album -> De Stijl, year -> 2000, US_peak_chart_post -> 66))
    

    【讨论】:

    • 谢谢。以及如何获得一个专辑类作为结果,或任何其他类?
    • 难道不是没有得到Album类作为你想要实现的结果吗?如果您想要实体,您的案例类版本是正确的。
    • 是的,你是对的;但我的问题是我希望尽可能少的耦合代码。因此,我希望有一种方法能够提取 json,同时能够重用以获取其他类和专辑的对象。
    • 返回一个无类型的Map[String, Any] 可能不是最好的主意,只是为了减少导出代码的数量......而且您需要手动为Album 定义一个构造函数以接收@ 987654328@.
    • 在我看来,将case class Album 连同从 JSON 中提取一个的方法一起发送并没有错。例如,如果您有两个子项目都需要引用 Album 但不需要相互依赖,只需将模型(和 json 解析器)提取到另一个“核心”或“公共”项目中,然后让你的子项目依赖它。
    猜你喜欢
    • 2016-08-11
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 2020-02-10
    • 2021-09-10
    • 1970-01-01
    相关资源
    最近更新 更多