• scala解析json —— json4s 解析json方法汇总


    使用json4s的框架,包括spark,flink

    1、org.json4s 引入pom的方法

    对于本地支持,引入以下依赖项添加到pom中

    <dependency>
      <groupId>org.json4s</groupId>
      <artifactId>json4s-jackson_${scala.version}</artifactId>
      <version>{latestVersion}</version>
    </dependency>

    对于jackson支持,引入以下依赖项添加到pom中

    <dependency>
      <groupId>org.json4s</groupId>
      <artifactId>json4s-jackson_${scala.version}</artifactId>
      <version>{latestVersion}</version>
    </dependency>

    2、Json4s 数据类型

    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)

    JField不再是JValue这意味着更高的类型安全性,因为不再可能创建无效的JSON,例如 JFields 直接添加到JArrays中,此更改最明显的结果是map、transform、find和filter有两种版本:

    def map(f: JValue => JValue): JValue
    def mapField(f: JField => JField): JValue
    def transform(f: PartialFunction[JValue, JValue]): JValue
    def transformField(f: PartialFunction[JField, JField]): JValue
    def find(p: JValue => Boolean): Option[JValue]
    def findField(p: JField => Boolean): Option[JField]

    3、使用org.json4s解析json字符串

     提取不嵌套的json串

    import org.json4s._
    import org.json4s.native.JsonMethods._
    
    // parse解析返回值为Jvalue
    scala> parse("""{"name":"Toy","price":35.35}""", useBigDecimalForDouble = true)
    res1: org.json4s.package.JValue = 
          JObject(List((name,JString(Toy)), (price,JDecimal(35.35))))

     提取json中的元素的值
    1)单层嵌套取单值

    //val parseJson: JValue = parse( """{"name":"Toy","price":35.35}""", useBigDecimalForDouble = true)
    val parseJson: JValue = parse( """{"name":"Toy","price":35.35}""")
    
    // 方法一:JString模式匹配方式
    val JString(name) = (parseJson  "name")
    println(name)
    
    //方法二:extract[String]提取值,
    val name:String = (parseJson  "name").extract[String] // 直接提取内容(不安全)
    val name:Option[String] = (parseJson  "name").extractOpt[String]// 返回Option类型(安全)
    val name: String = (parseJson  "name").extractOrElse[String]("") // 设置默认值

    2)多层嵌套套取单值

    val parseJson: JValue = parse( """{"name":{"tome":"new"},"price":35.35}""", useBigDecimalForDouble = true)
    println(parseJson)
    // 方法一:逐层访问
    val value: String = (parseJson  "name"  "tome").extract[String]
    // 方法二:循环访问
    val value: String = (parseJson \ "tome").extract[String]

    解析提取数组的json串

    简单值数组

    // 解析列表
    parse(""" { "numbers" : [1, 2, 3, 4] } """)
    res0: org.json4s.JsonAST.JValue =
          JObject(List((numbers,JArray(List(JInt(1), JInt(2), JInt(3), JInt(4))))))
    
    // 程序解析
    val listValue : List[BigInt]  = for {JArray(child) <- jArray; JInt(value) <- child} yield value
    
    listValue.map(println)

    嵌套数组json串解析

    val json = parse(
          """
             { "name": "joe",
               "children": [
                 {
                   "name": "Mary",
                   "age": 5
                 },
                 {
                   "name": "Mazy",
                   "age": 3
                 }
               ]
             }
          """)
    
    // 嵌套返回值
    for (JArray(child) <- json) println(child)
    res0: List(JObject(List((name,JString(Mary)), (age,JInt(5)))), JObject(List((name,JString(Mazy)), (age,JInt(3)))))
    
    // 嵌套取数组中某个字段值
    for {
       JObject(child) <- json
       JField("age", JInt(age)) <- child
    } yield age
    
    // 嵌套取数组中某个字段值,并添加过滤
    for {
      JObject(child) <- json
      JField("name", JString(name)) <- child
      JField("age", JInt(age)) <- child
      if age > 4
    } yield (name, age)

    json和对象的转换

    /** json转化为对象(不带外层字段) **/
    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)
    
    /** json转对象(带外层字段名) */
    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)

    4、使用org.json4s产生json字符串

    基本数据类型转化为普通json
    1) 序列Seq转化为Json字符串

    scala> val json = List(1, 2, 3)
    
    scala> compact(render(json))
    res0: String = [1,2,3]

    2) Tuple2[String, A] 类型转化为json字符串

    scala> val json = ("name" -> "joe")
    
    scala> compact(render(json))
    res1: String = {"name":"joe"}

    3) ~ 合并object对象转化为json串

    scala> val json = ("name" -> "joe") ~ ("age" -> 35)
    
    scala> compact(render(json))
    res2: String = {"name":"joe","age":35}

    4) option 类型转化为串

    scala> val json = ("name" -> "joe") ~ ("age" -> Some(35))
    
    scala> compact(render(json))
    res3: String = {"name":"joe","age":35}
    
    scala> val json = ("name" -> "joe") ~ ("age" -> (None: Option[Int]))
    
    scala> compact(render(json))
    res4: String = {"name":"joe"}

    5) case class 类转化为Json串

    object JsonExample extends App {
      import org.json4s._
      import org.json4s.JsonDSL._
      import org.json4s.jackson.JsonMethods._
    
      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)
    
      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)))
    }

    5、使用org.json4s其他用法

    1) 格式化json串

    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]
        }]
      }
    }

    2) 合并两个json 串

    scala> import org.json4s._
    scala> import org.json4s.jackson.JsonMethods._
    
    scala> val lotto1 = parse("""{
             "lotto":{
               "lotto-id":5,
               "winning-numbers":[2,45,34,23,7,5,3],
               "winners":[{
                 "winner-id":23,
                 "numbers":[2,45,34,23,3,5]
               }]
             }
           }""")
    
    scala> val lotto2 = parse("""{
             "lotto":{
               "winners":[{
                 "winner-id":54,
                 "numbers":[52,3,12,11,18,22]
               }]
             }
           }""")
    
    scala> val mergedLotto = lotto1 merge lotto2
    
    scala> pretty(render(mergedLotto))
    res0: String =
    {
      "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]
        }]
      }
    }

    3) 两个json 串查找差异

    scala> val Diff(changed, added, deleted) = mergedLotto diff lotto1
    changed: org.json4s.JsonAST.JValue = JNothing
    added: org.json4s.JsonAST.JValue = JNothing
    deleted: org.json4s.JsonAST.JValue = JObject(List((lotto,JObject(List(JField(winners,
    JArray(List(JObject(List((winner-id,JInt(54)), (numbers,JArray(
    List(JInt(52), JInt(3), JInt(12), JInt(11), JInt(18), JInt(22))))))))))))))

    > 参考链接:https://blog.csdn.net/leehbing/article/details/74391308

  • 相关阅读:
    hdu 1253
    poj 2531 Network Saboteur
    rwkj 1501 数据结构:图的DFS遍历
    rwkj 1306 素数========拓展
    nyist 91 阶乘之和
    nyist 65 另一种阶乘问题
    nyist 31 5个数求最值
    nyist 22 素数求和
    向量 vector
    字符串 统计 ,删除,连接,变换
  • 原文地址:https://www.cnblogs.com/yyy-blog/p/11819302.html
Copyright © 2020-2023  润新知