FastJson在scala中序列化與反序列化

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對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章