Java Development Tool scala Processing json Format Sharp Tool json4s Detailed Explanation
- 2021-08-28 20:13:37
- OfStack
1. Why json4s
Official description from 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.
In the scala library, There are at least 6 json libraries, And does not include the json library of java, These libraries all have a similar abstract syntax tree AST, The purpose of json4s is to support these json libraries using a simple syntax, Therefore, json4s can be said to be a standard treatment of json, With the extremely brief syntax features in the development of scala, It can easily realize json merging, diff operation of json, and can easily process jsonArray strings, so if scala is used, json4s1 must not be missed. It is very common to use json to process data in actual scenarios, such as processing original json data in spark development, etc. It may seem complicated to get started, but you will be very comfortable to use.
2. Data structure of json4s
json4s consists of 10 types and 1 object of type type, as follows
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)
It can be seen that they all inherit from JValue, JValue is the object status similar to java in json4s, and JField is prepared for once matching key and value pairs of json.
3. Practice of json4s
Let's see how we can use json4s
<dependency>
<groupId>org.json4s</groupId>
<artifactId>json4s-native_2.11</artifactId>
<version>3.7.0-M6</version>
</dependency>
Look at the following code can, comments written more clearly, 1 generally speaking, the use of json is nothing more than string to object or object to string, and string to object can use case class can also use the original such as the class mentioned above
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 Method represents the value from a string to the json-object
val person = parse(
"""
|{"name":"Toy","price":35.35}
|""".stripMargin, useBigDecimalForDouble = true)
// 1. Pattern matching extraction, \ Presentation extraction
val JString(name) = (person \ "name")
println(name)
// 2.extract[String] Value
// 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. Multi-layer embedding value
val parseJson: JValue = parse(
"""
|{"name":{"tome":"new"},"price":35.35}
|""".stripMargin, useBigDecimalForDouble = true)
//3.1 Layer-by-layer access
val value = (parseJson \ "name" \ "tome").extract[String]
//3.2 Iterate access
val value2 = (parseJson \\ "tome")
println(value2)
//4. Nesting json String parsing
val json = parse(
"""
{ "name": "joe",
"children": [
{
"name": "Mary",
"age": 20
},
{
"name": "Mazy",
"age": 10
}
]
}
""")
// println(json \ "children")
// Pattern matching
for (JArray(child) <- json) println(child)
// Extraction object Under The value of a field
val ages = for {
JObject(child) <- json
JField("age", JInt(age)) <- child
} yield age
println(ages)
// Embedding the value of a field in the array and adding a filter
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 And object conversion ,[ Is json Array ]
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 Turn the object, [json Non json Array, but each level should be clear ]
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. Use org.json4s Produce json String
// 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 Formatting
println(pretty(render(jsonCase)))
// 9. Merge strings
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. String to find differences
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. Traversal json , using 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(","))
}
}
}
Step 4 Attention
4.1 Use of compact and render
Commonly used writing
compact(render(json))
Used to convert an json object into a string and compress it. Of course, you can also use
prety(render(json))
4.2 Requires 1 Implicit Object for Serialization
For example, the following
implicit val formats = Serialization.formats(NoTypeHints)
Reference
https://json4s.org/
https://github.com/json4s/json4s/tree/v.3.2.0_scala2.10
https://www.cnblogs.com/yyy-blog/p/11819302.html
https://www.shuzhiduo.com/A/Vx5MBVOYdN/
https://segmentfault.com/a/1190000007302496
https://www.coder.work/article/6786418
https://www.wolai.com/sTVar6XXjpuM9ANFn2sx9n
https://www.wolai.com/sTVar6XXjpuM9ANFn2sx9n