FastJson與Gson在scala中序列化與反序列化
Alibaba的一款開源JSON組件FastJson,非常好用,在序列化和反序列化方面性能突出,而且API接口簡單易用,算是處理JSON的一大利器
首先,添加依賴,注意這裏的版本號,務必使用最新版本,因爲1.2.58以下的低版本在反序列化的時候存在漏洞,容易被黑客利用攻擊服務器,最新版本可以參考官網FastJson的具體版號
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.59</version>
</dependency>
序列化
假設我們有一個Person類,定義在Person.scala中。這裏面需要注意下Person的主構造函數根據類的定義是無參的,新定義的輔助構造函數必須先調用主構造函數,然後可以輔助構造函數的構建,輔助構造函數可以定義多個。
Person類中有年齡、性別、學分、住址、興趣愛好等基本屬性
這裏必須帶上屬性的setter方法,因爲setter在FastJson反序列化的時候會用到,這個待會再看
case class AppInterest(var news:String,var video:String)
case class Address(var province:String,var city:String,var distinct:String)
case class Interest(var appInterest:AppInterest)
class Person {
var name:String = _
var age:Int = _
var score:Array[Int] = _
var address:Address = _
var interest:Interest = _
def this(name:String, age:Int,score:Array[Int], address:Address,interest:Interest){
this() // 調用主構造函數
this.name = name
this.age = age
this.score = score
this.address = address
this.interest = interest
}
def getName():String = this.name
def getAge():Int = this.age
def getScore():Array[Int] = this.score
def getAddress():Address = this.address
def getInterest():Interest = this.interest
def setName(name:String):Unit = {
this.name = name
}
def setAge(age:Int):Unit = {
this.age = age
}
def setScore(score:Array[Int]):Unit = {
this.score = score
}
def setAddress(address:Address):Unit = {
this.address = address
}
}
來看測試情況
package LBS
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.{SerializeConfig, SerializerFeature}
object Tmp {
def main(args: Array[String]): Unit = {
val person1 = new Person("豬可愛", 18, Array(1, 2, 3, 4, 5), Address("HuBei", "WuHan", "HongShan"),
Interest(AppInterest("political", "entertainment")))
val str = JSON.toJSONString(person1, true)
// val str = JSON.toJSONString(person1, SerializerFeature.EMPTY:_*) // 或者這樣
println(str)
}
}
如果沒有getter方法,輸出就是一個空的JSON字符串"{}",現在有了getter,輸出如下,可以看到address和interest對象所在的類沒有getter方法,導致他們的序列化出來但就是空的
{"address":{},"age":18,"interest":{},"name":"豬可愛","score":[1,2,3,4,5]}
如果修改下Address的類定義,添加上屬性的getter方法,就能正確的序列化出來
case class Address(var province:String,var city:String,var distinct:String){
def getProvince():String = province
def getCity:String = city
def getDistinct:String = distinct
}
那麼得到的結果如下,也就是需要所有需要序列化的類都有getter方法纔可以正確序列化
{
"address":{
"city":"WuHan",
"distinct":"HongShan",
"province":"HuBei"
},
"age":18,
"interest":{},
"name":"豬可愛",
"score":[1,2,3,4,5]
}
那也沒有辦法不寫getter方法就完成序列化呢,我們先註釋getter方法,開啓序列化配置SerializeConfig,它能加載序列化器
case class AppInterest(var news:String,var video:String)
case class Address(var province:String,var city:String,var distinct:String)
case class Interest(var appInterest:AppInterest)
class Person {
var name:String = _
var age:Int = _
var score:Array[Int] = _
var address:Address = _
var interest:Interest = _
def this(name:String, age:Int,score:Array[Int], address:Address,interest:Interest){
this() // 調用主構造函數
this.name = name
this.age = age
this.score = score
this.address = address
this.interest = interest
}
// def getName():String = this.name
// def getAge():Int = this.age
// def getScore():Array[Int] = this.score
// def getAddress():Address = this.address
// def getInterest():Interest = this.interest
def setName(name:String):Unit = {
this.name = name
}
def setAge(age:Int):Unit = {
this.age = age
}
def setScore(score:Array[Int]):Unit = {
this.score = score
}
def setAddress(address:Address):Unit = {
this.address = address
}
}
測試結果
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.{SerializeConfig, SerializerFeature}
object Tmp {
def main(args: Array[String]): Unit = {
val person1 = new Person("豬可愛", 18, Array(1, 2, 3, 4, 5), Address("HuBei", "WuHan", "HongShan"),
Interest(AppInterest("political", "entertainment")))
// val str = JSON.toJSONString(person1, true)
// val str = JSON.toJSONString(person1, SerializerFeature.EMPTY:_*) // 或者這樣
val conf = new SerializeConfig(true)
val str = JSON.toJSONString(person1, conf)
println(str)
}
}
結果如下
{"address":{"city":"WuHan","distinct":"HongShan","province":"HuBei"},"age":18,"interest":{"appInterest":{"news":"political","video":"entertainment"}},"name":"豬可愛","score":[1,2,3,4,5]}
對象數組序列化示例
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.{SerializeConfig, SerializerFeature}
import scala.collection.mutable.ArrayBuffer
object Tmp {
def main(args: Array[String]): Unit = {
val person1 = new Person("豬可愛", 18, Array(1, 2, 3, 4, 5), Address("HuBei", "WuHan", "HongShan"),
Interest(AppInterest("political", "entertainment")))
val person2 = new Person("豬可愛", 18, Array(1, 2, 3, 4, 5), Address("HuBei", "WuHan", "HongShan"),
Interest(AppInterest("political", "entertainment")))
val arr = new ArrayBuffer[Person]()
arr.append(person1)
arr.append(person2)
val conf = new SerializeConfig(true)
val str2 = JSON.toJSONString(arr.toArray, conf)
println(str2)
}
}
結果如下
[{"address":{"city":"WuHan","distinct":"HongShan","province":"HuBei"},"age":18,"interest":{"appInterest":{"news":"political","video":"entertainment"}},"name":"豬可愛","score":[1,2,3,4,5]},{"address":{"city":"WuHan","distinct":"HongShan","province":"HuBei"},"age":18,"interest":{"appInterest":{"news":"political","video":"entertainment"}},"name":"豬可愛","score":[1,2,3,4,5]}]
反序列化
我們拿上面單個Person序列化後的字符串做反序列化測試,就目前看到的反序列化的時候必須有setter方法,反序列化的時候會用到
import com.alibaba.fastjson.JSON
object Tmp {
def main(args: Array[String]): Unit = {
val ss = """{"address":{"city":"WuHan","distinct":"HongShan","province":"HuBei"},"age":18,"interest":{"appInterest":{"news":"political","video":"entertainment"}},"name":"豬可愛","score":[1,2,3,4,5]}"""
val person: Person = JSON.parseObject(ss, classOf[Person])
println(person.address.province)
}
}
結果如下
HuBei
反序列化簡單的字符串示例
import com.alibaba.fastjson.JSON
object Tmp {
def main(args: Array[String]): Unit = {
val ss = """{"name":"豬可愛","age":18,"score":[1,2,3,4,5]}"""
val pJosn = JSON.parseObject(ss)
val score = JSON.parseArray(pJosn.getString("score"), classOf[Int])
println(score.toString)
println(pJosn.getInteger("age"))
println(pJosn.getString("name"))
println(pJosn.getOrDefault("education", "unknown"))
}
}
結果如下
[1, 2, 3, 4, 5]
18
豬可愛
unknown
Gson的序列化與反序列化
Gson是Google開源的一塊功能全面、易用的JSON組件
添加依賴
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
序列化與反序列化
import com.google.gson.Gson
import com.google.gson.JsonObject
object Tmp {
def main(args: Array[String]): Unit = {
val ss = """{"address":{"city":"WuHan","distinct":"HongShan","province":"HuBei"},"age":18,"interest":{"appInterest":{"news":"political","video":"entertainment"}},"name":"豬可愛","score":[1,2,3,4,5]}"""
val gson = new Gson()
// 反序列化
val person = gson.fromJson(ss, classOf[Person])
// 序列化
println(gson.toJson(person))
// 反序列化簡單字符串
val str = """{"name":"豬可愛","age":18,"score":[1,2,3,4,5]}"""
val pJson = gson.fromJson(str, classOf[JsonObject])
val a = Some(pJson.get("name"))
println(a.getOrElse("default"))
}
}
參考
1 FastJson官網
2 fastjson序列化原理詳解
3 FastJson反序列化的前世今生
4 FastJson 反序列化注意事項
5 fastjson序列化scala對象