溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何來使用json4s

發(fā)布時間:2021-12-08 14:40:45 來源:億速云 閱讀:157 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“如何來使用json4s”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何來使用json4s”吧!

1.為什么是json4s

從json4s的官方描述

At this moment there are at least 6 json libraries for scala, not counting the java json libraries. All these libraries have a very similar AST. This project aims to provide a single AST to be used by other scala json libraries. At this moment the approach taken to working with the AST has been taken from lift-json and the native package is in fact lift-json but outside of the lift project.

在scala庫中,至少有6個json庫,并且不包括 java的json庫,這些庫都有著類似的抽象語法樹AST,json4s的目的就是為了使用簡單的一種語法支持這些json庫,因此說json4s可以說是一種json的規(guī)范處理,配合scala開發(fā)過程中極其簡介的語法特性,可以輕松地實現(xiàn)比如json合并,json的diff操作,可以方便地處理jsonArray的字符串,所以如果使用scala,那么json4s一定不能錯過,在實際場景下使用json處理數(shù)據(jù)很常見,比如spark開發(fā)中處理原始json數(shù)據(jù)等等,開始上手可能看起來比較復(fù)雜,但是用起來你會很爽。

2.json4s的數(shù)據(jù)結(jié)構(gòu)

json4s包括10個類型和一個type類型的對象,分別如下

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 JLong(num: Long) 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)

可以看到,他們都繼承自JValue,JValue是json4s里面類似于java的object地位,而JField是用來一次性匹配json的key,value對而準(zhǔn)備的。

3.json4s的實踐

下面來看,我們?nèi)绾蝸硎褂胘son4s

<dependency>
    <groupId>org.json4s</groupId>
    <artifactId>json4s-native_2.11</artifactId>
    <version>3.7.0-M6</version>
</dependency>

看下面的代碼即可,注釋寫的比較清晰,一般來說json的使用無外乎是字符串到對象或者對象到字符串,而字符串到對象可以用case class 也可以用原始的比如上面提到的類

package com.hoult.scala.json4s
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._

object Demo1 {
  def main(args: Array[String]): Unit = {

    //parse方法表示從字符串到j(luò)son-object
    val person = parse(
      """
        |{"name":"Toy","price":35.35}
        |""".stripMargin, useBigDecimalForDouble = true)
    // 1.模式匹配提取, \表示提取
    val JString(name) = (person \ "name")
    println(name)

    // 2.extract[String]取值
//    implicit val formats = org.json4s.Formats
    implicit val formats = DefaultFormats
    val name2 = (person \ "name").extract[String]
    val name3 = (person \ "name").extractOpt[String]
    val name4 = (person \ "name").extractOrElse("")

    // 3.多層嵌套取值
    val parseJson: JValue = parse(
      """
        |{"name":{"tome":"new"},"price":35.35}
        |""".stripMargin, useBigDecimalForDouble = true)

    //3.1 逐層訪問
    val value = (parseJson \ "name" \ "tome").extract[String]
    //3.2 循環(huán)訪問
    val value2 = (parseJson \\ "tome")
    println(value2)


    //4.嵌套json串解析
    val json = parse(
      """
         { "name": "joe",
           "children": [
             {
               "name": "Mary",
               "age": 20
             },
             {
               "name": "Mazy",
               "age": 10
             }
           ]
         }
      """)

//    println(json \ "children")

    //模式匹配
    for (JArray(child) <- json) println(child)

    //提取object 下 某字段的值
    val ages = for {
      JObject(child) <- json
      JField("age", JInt(age)) <- child
    } yield age

    println(ages)

    // 嵌套取數(shù)組中某個字段值,并添加過濾
    val nameAges = for {
      JObject(child) <- json
      JField("name", JString(name)) <- child
      JField("age", JInt(age)) <- child
      if age > 10
    } yield (name, age)

    println(nameAges)

    // 5.json和對象的轉(zhuǎn)換,[就是json數(shù)組]
    case class ClassA(a: Int, b: Int)

    val json2: String = """[{"a":1,"b":2},{"a":1,"b":2}]"""

    val bb: List[ClassA] = parse(json2).extract[List[ClassA]]
    println(bb)

    // 6.json轉(zhuǎn)對象,[json 非json數(shù)組,但是每個級別要明確]
    case class ClassC(a: Int, b: Int)

    case class ClassB(c: List[ClassC])

    val json3: String = """{"c":[{"a":1,"b":2},{"a":1,"b":2}]}"""

    val cc: ClassB = parse(json3).extract[ClassB]
    println(cc)

    // 7.使用org.json4s產(chǎn)生json字符串
//    import org.json4s.JsonDSL._
    val json1 = List(1, 2, 3)
    val jsonMap = ("name" -> "joe")
    val jsonUnion = ("name" -> "joe") ~ ("age" -> 10)
    val jsonOpt = ("name" -> "joe") ~ ("age" -> Some(1))
    val jsonOpt2 = ("name" -> "joe") ~ ("age" -> (None: Option[Int]))
    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(10, List(1, 2, 5)), Winner(11, List(1, 2, 0)))
    val lotto = Lotto(11, List(1, 2, 5), winners, None)

    val jsonCase =
      ("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(json1)))
    println(compact(render(jsonMap)))
    println(compact(render(jsonUnion)))
    println(compact(render(jsonOpt)))
    println(compact(render(jsonOpt2)))
    println(compact(render(jsonCase)))

    // 8.json格式化
    println(pretty(render(jsonCase)))

    // 9.合并字符串
    val lotto1 = parse("""{
         "lotto":{
           "lotto-id": 1,
           "winning-numbers":[7,8,9],
           "winners":[{
             "winner-id": 1,
             "numbers":[7,8,9]
           }]
         }
       }""")

    val lotto2 = parse("""{
         "lotto":{
           "winners":[{
             "winner-id": 2,
             "numbers":[1,23,5]
           }]
         }
       }""")

    val mergedLotto = lotto1 merge lotto2
//    println(pretty(render(mergedLotto)))

    // 10.字符串尋找差異
    val Diff(changed, added, deleted) = mergedLotto diff lotto1
    println(changed)
    println(added)
    println(deleted)

    val json10 = parse(
      """

      """)

    println("********8")
    println(json10)
    for (JObject(j) <- json10) println(j)

    println("********11")

    // 11.遍歷json,使用for
    // key1 values key1_vk1:v1 ....
    val str = "{\"tag_name\":\"t_transaction_again_day\",\"tag_distribute_json\":\"{\\\"1\\\":\\\"0.0011231395\\\",\\\"0\\\":\\\"0.9988768605\\\"}\"}"

    val valueJson = parse(str) \ "tag_distribute_json"
    println(valueJson)
    for {
      JString(obj) <- valueJson
      JObject(dlist) <- parse(obj)
      (key, JString(value))<- dlist
    } {
      println(key + "::" + value)
//      val kvList = for (JObject(key, value) <- parse(obj)) yield (key, value)
//      println("obj : " + kvList.mkString(","))
    }
  }
}

4.注意

4.1 compact 和 render的使用

常用寫法compact(render(json)),用來把一個json對象轉(zhuǎn)成字符串,并壓縮顯示,當(dāng)然也可以用prety(render(json))

4.2 序列化時候需要一個隱式對象

例如下面的

implicit val formats = Serialization.formats(NoTypeHints)

感謝各位的閱讀,以上就是“如何來使用json4s”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何來使用json4s這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI