在不指定大小写的情况下将任何 JSON 解析为 JValue class

Parse any JSON to JValue without specifying a case class

我试着解释得更好。

我正在从 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 作为 "BluePrint":

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

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

非常感谢

嗯,任何 JSON 对象都可以提取到 Map,任何 JSON 数组都可以提取到 Seq。但是,使用 Map[String, Any] 不太方便,而且没有比指定 case class 更简单的方法来提取类型安全结构。

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))