Java开发工具-scala处理json格式利器-json4s详解
1.为什么是json4s
从json4s的官方描述
Atthismomentthereareatleast6jsonlibrariesforscala,notcountingthejavajsonlibraries.AlltheselibrarieshaveaverysimilarAST.ThisprojectaimstoprovideasingleASTtobeusedbyotherscalajsonlibraries.
AtthismomenttheapproachtakentoworkingwiththeASThasbeentakenfromlift-jsonandthenativepackageisinfactlift-jsonbutoutsideoftheliftproject.
在scala库中,至少有6个json库,并且不包括java的json库,这些库都有着类似的抽象语法树AST,json4s的目的就是为了使用简单的一种语法支持这些json库,因此说json4s可以说是一种json的规范处理,配合scala开发过程中极其简介的语法特性,可以轻松地实现比如json合并,json的diff操作,可以方便地处理jsonArray的字符串,所以如果使用scala,那么json4s一定不能错过,在实际场景下使用json处理数据很常见,比如spark开发中处理原始json数据等等,开始上手可能看起来比较复杂,但是用起来你会很爽。
2.json4s的数据结构
json4s包括10个类型和一个type类型的对象,分别如下
caseobjectJNothingextendsJValue//'zero'forJValue caseobjectJNullextendsJValue caseclassJString(s:String)extendsJValue caseclassJDouble(num:Double)extendsJValue caseclassJDecimal(num:BigDecimal)extendsJValue caseclassJInt(num:BigInt)extendsJValue caseclassJLong(num:Long)extendsJValue caseclassJBool(value:Boolean)extendsJValue caseclassJObject(obj:List[JField])extendsJValue caseclassJArray(arr:List[JValue])extendsJValue typeJField=(String,JValue)
可以看到,他们都继承自JValue,JValue是json4s里面类似于java的object地位,而JField是用来一次性匹配json的key,value对而准备的。
3.json4s的实践
下面来看,我们如何来使用json4s
org.json4s json4s-native_2.11 3.7.0-M6
看下面的代码即可,注释写的比较清晰,一般来说json的使用无外乎是字符串到对象或者对象到字符串,而字符串到对象可以用caseclass也可以用原始的比如上面提到的类
packagecom.hoult.scala.json4s importorg.json4s._ importorg.json4s.JsonDSL._ importorg.json4s.native.JsonMethods._ objectDemo1{ defmain(args:Array[String]):Unit={ //parse方法表示从字符串到json-object valperson=parse( """ |{"name":"Toy","price":35.35} |""".stripMargin,useBigDecimalForDouble=true) //1.模式匹配提取,\表示提取 valJString(name)=(person\"name") println(name) //2.extract[String]取值 //implicitvalformats=org.json4s.Formats implicitvalformats=DefaultFormats valname2=(person\"name").extract[String] valname3=(person\"name").extractOpt[String] valname4=(person\"name").extractOrElse("") //3.多层嵌套取值 valparseJson:JValue=parse( """ |{"name":{"tome":"new"},"price":35.35} |""".stripMargin,useBigDecimalForDouble=true) //3.1逐层访问 valvalue=(parseJson\"name"\"tome").extract[String] //3.2循环访问 valvalue2=(parseJson\\"tome") println(value2) //4.嵌套json串解析 valjson=parse( """ {"name":"joe", "children":[ { "name":"Mary", "age":20 }, { "name":"Mazy", "age":10 } ] } """) //println(json\"children") //模式匹配 for(JArray(child)<-json)println(child) //提取object下某字段的值 valages=for{ JObject(child)<-json JField("age",JInt(age))<-child }yieldage println(ages) //嵌套取数组中某个字段值,并添加过滤 valnameAges=for{ JObject(child)<-json JField("name",JString(name))<-child JField("age",JInt(age))<-child ifage>10 }yield(name,age) println(nameAges) //5.json和对象的转换,[就是json数组] caseclassClassA(a:Int,b:Int) valjson2:String="""[{"a":1,"b":2},{"a":1,"b":2}]""" valbb:List[ClassA]=parse(json2).extract[List[ClassA]] println(bb) //6.json转对象,[json非json数组,但是每个级别要明确] caseclassClassC(a:Int,b:Int) caseclassClassB(c:List[ClassC]) valjson3:String="""{"c":[{"a":1,"b":2},{"a":1,"b":2}]}""" valcc:ClassB=parse(json3).extract[ClassB] println(cc) //7.使用org.json4s产生json字符串 //importorg.json4s.JsonDSL._ valjson1=List(1,2,3) valjsonMap=("name"->"joe") valjsonUnion=("name"->"joe")~("age"->10) valjsonOpt=("name"->"joe")~("age"->Some(1)) valjsonOpt2=("name"->"joe")~("age"->(None:Option[Int])) caseclassWinner(id:Long,numbers:List[Int]) caseclassLotto(id:Long,winningNumbers:List[Int],winners:List[Winner],drawDate:Option[java.util.Date]) valwinners=List(Winner(10,List(1,2,5)),Winner(11,List(1,2,0))) vallotto=Lotto(11,List(1,2,5),winners,None) valjsonCase= ("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.合并字符串 vallotto1=parse("""{ "lotto":{ "lotto-id":1, "winning-numbers":[7,8,9], "winners":[{ "winner-id":1, "numbers":[7,8,9] }] } }""") vallotto2=parse("""{ "lotto":{ "winners":[{ "winner-id":2, "numbers":[1,23,5] }] } }""") valmergedLotto=lotto1mergelotto2 //println(pretty(render(mergedLotto))) //10.字符串寻找差异 valDiff(changed,added,deleted)=mergedLottodifflotto1 println(changed) println(added) println(deleted) valjson10=parse( """ """) println("********8") println(json10) for(JObject(j)<-json10)println(j) println("********11") //11.遍历json,使用for //key1valueskey1_vk1:v1.... valstr="{\"tag_name\":\"t_transaction_again_day\",\"tag_distribute_json\":\"{\\\"1\\\":\\\"0.0011231395\\\",\\\"0\\\":\\\"0.9988768605\\\"}\"}" valvalueJson=parse(str)\"tag_distribute_json" println(valueJson) for{ JString(obj)<-valueJson JObject(dlist)<-parse(obj) (key,JString(value))<-dlist }{ println(key+"::"+value) //valkvList=for(JObject(key,value)<-parse(obj))yield(key,value) //println("obj:"+kvList.mkString(",")) } } }
4.注意
4.1compact和render的使用
常用写法compact(render(json)),用来把一个json对象转成字符串,并压缩显示,当然也可以用prety(render(json))
4.2序列化时候需要一个隐式对象
例如下面的
implicitvalformats=Serialization.formats(NoTypeHints)
参考
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
到此这篇关于开发工具-scala处理json格式利器-json4s的文章就介绍到这了,更多相关scala处理json格式利器-json4s内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。