Json4s

在寫spark項(xiàng)目時(shí)遇到scala對(duì)象與json對(duì)象之間轉(zhuǎn)換的問題,花點(diǎn)時(shí)間總結(jié)一下。

Json4s介紹

Json4s下面有兩個(gè)類型的包

  • Lift Json
import org.json4s._
import org.json4s.native.JsonMethods._

native package具有l(wèi)ift-json的所有功能。

  • Jackson
import org.json4s._
import org.josn4s.jackson.JsonMethods._

與native package不同的是,jackson包含了大部分jackson-module-scala的功能,也可以使用lift-json下的所有功能。在這個(gè)項(xiàng)目中我們使用jackson。

Json AST

lift-json library 的核心就是Json AST,它將Json對(duì)象轉(zhuǎn)換成了語法樹。

sealed abstract class JValue
case object JNothing extends JValue // 'zero' for JValue
case object JNull extends JValue
case class JString(s: String) extends JValue
case class JDouble(num: Double) extends JValue
case class JDecimal(num: BigDecimal) extends JValue
case class JInt(num: BigInt) extends JValue
case class JBool(value: Boolean) extends JValue
case class JObject(obj: List[JField]) extends JValue
case class JArray(arr: List[JValue]) extends JValue

type JField = (String, JValue)

轉(zhuǎn)換的常見方式有:

  • Json DSL(implicit)
  • String parse
  • case class

下面一一介紹。

Json4s安裝

  • SBT users
  • native support
val json4sNative = "org.json4s" %% "json4s-native" % "{latestVersion}"
  • jackson support
val json4sJackson = "org.json4s" %% "json4s-jackson" % "{latestVersion}"
  • Maven users
  • native support
<dependency>
  <groupId>org.json4s</groupId>
  <artifactId>json4s-native_${scala.version}</artifactId>
  <version>{latestVersion}</version>
</dependency>
  • jackson support
<dependency>
  <groupId>org.json4s</groupId>
  <artifactId>json4s-jackson_${scala.version}</artifactId>
  <version>{latestVersion}</version>
</dependency>

JSON轉(zhuǎn)換

這里我們都以jackson為例,native support請(qǐng)參考http://json4s.org/
一個(gè)有效的json對(duì)象可以轉(zhuǎn)換成AST格式

String parse
import org.json4s._
import org.json4s.jackson.JsonMethods._
parse("""{ "numbers" : [1, 2, 3, 4] }""")
parse("""{"name":"Toy","price":35.35}""", useBigDecimalForDouble = true)
DSL Parse

任意scala原始對(duì)象與json原始對(duì)象之間的轉(zhuǎn)換

#List to json
scala> val json = List(1, 2, 3)
scala> compact(render(json))
res0: String = [1,2,3]
#Map to json
scala> val json = ("name" -> "joe")
scala> compact(render(json))
res1: String = {"name":"joe"}
#當(dāng)有多行數(shù)據(jù)時(shí),用~符號(hào)連接
scala> val json = ("name" -> "joe") ~ ("age" -> 35)
scala> compact(render(json))
res2: String = {"name":"joe","age":35}
case class

當(dāng)你有自定義的數(shù)據(jù)類型想進(jìn)行轉(zhuǎn)換時(shí),可以使用下面的方法

type DslConversion = T => JValue
object JsonExample extends App {
  import org.json4s._
  import org.json4s.JsonDSL._
  import org.json4s.jackson.JsonMethods._
  
  #定義類 Winner, Lotto
  case class Winner(id: Long, numbers: List[Int])
  case class Lotto(id: Long, winningNumbers: List[Int], winners: List[Winner], drawDate: Option[java.util.Date])

  val winners = List(Winner(23, List(2, 45, 34, 23, 3, 5)), Winner(54, List(52, 3, 12, 11, 18, 22)))
  val lotto = Lotto(5, List(2, 45, 34, 23, 7, 5, 3), winners, None)
  
  #轉(zhuǎn)換json
  val json =
    ("lotto" ->
      ("lotto-id" -> lotto.id) ~
      ("winning-numbers" -> lotto.winningNumbers) ~
      ("draw-date" -> lotto.drawDate.map(_.toString)) ~
      ("winners" ->
        lotto.winners.map { w =>
          (("winner-id" -> w.id) ~
           ("numbers" -> w.numbers))}))

  println(compact(render(json)))
}
scala> JsonExample
{"lotto":{"lotto-id":5,"winning-numbers":[2,45,34,23,7,5,3],"winners":
[{"winner-id":23,"numbers":[2,45,34,23,3,5]},{"winner-id":54,"numbers":[52,3,12,11,18,22]}]}}

如果想將結(jié)果打印出來,可以使用

scala> pretty(render(JsonExample.json))

{
  "lotto":{
    "lotto-id":5,
    "winning-numbers":[2,45,34,23,7,5,3],
    "winners":[{
      "winner-id":23,
      "numbers":[2,45,34,23,3,5]
    },{
      "winner-id":54,
      "numbers":[52,3,12,11,18,22]
    }]
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容