眾所周知,java bean的寫法會影響fastjson的解析,那么當(dāng)使用kotlin的時(shí)候怎么寫bean類才能保證fastjson能夠正常的工作不挖坑呢?
分兩種情況:
一、使用kotlin-reflect庫
以下寫法使用標(biāo)準(zhǔn)庫和Android專用庫都可以正常解析
data class KItem constructor(var id: Int? = null, var name: String? = null) {
override fun toString(): String = "{name =$name,id =$id}"
}
class JItem1 {
var id: Int = 0
var name: String = ""
override fun toString(): String = "{name =$name,id =$id}"
}
class JItem2 constructor(var id: Int = 0, var name: String = "") {
override fun toString(): String = "{name =$name,id =$id}"
}
必要的配置
- build.gradle
implementation 'com.alibaba:fastjson:1.2.75'
// implementation 'com.alibaba:fastjson:1.1.72.android'
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
- proguard-rules.pro
#keep整個(gè)bean類
-keep class com.song.project.test.TestActivity$*{*;}
#keep插件 ,必須要
-keep class kotlin.*.* { *; }
二、使用fastjson自帶的@JSONCreator
1、android專用庫
以下三種寫法都可以正常解析
data class KItem @JSONCreator constructor(var id: Int? = null, var name: String? = null) {
override fun toString(): String = "{name =$name,id =$id}"
}
class JItem1 {
var id: Int = 0
var name: String = ""
override fun toString(): String = "{name =$name,id =$id}"
}
class JItem2 @JSONCreator constructor(var id: Int = 0, var name: String = "") {
override fun toString(): String = "{name =$name,id =$id}"
}
2.使用fastjson標(biāo)準(zhǔn)庫
只有JItem1可以解析(實(shí)質(zhì)上此種寫法在本文測試的幾種情況下都是可以的)
class JItem1 {
var id: Int = 0
var name: String = ""
override fun toString(): String = "{name =$name,id =$id}"
}
必要的配置
- proguard-rules.pro
#keep整個(gè)bean類
-keep class com.song.project.test.TestActivity$*{*;}
三 、總結(jié):
- 使用kotlin-reflect庫,
優(yōu)點(diǎn):一般寫法都可以支持,通用性好
槽點(diǎn): 需要額外依賴庫,并且需要配置混淆 - 使用@JSONCreator
優(yōu)點(diǎn):使用方便
槽點(diǎn):只有Android庫可以生效
四、其他
- 測試版本:android專用庫1.1.72/1.1.71 標(biāo)準(zhǔn)庫 1.2.74/1.2.75
- 本文中測試的場景為:release包且混淆開啟
附:測試代碼
class TestActivity : AppCompatActivity() {
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
textView = TextView(this)
textView.textSize = 18f
setContentView(textView)
textView.setOnClickListener {
test()
}
textView.performClick()
}
private fun test() {
val list = createTestData()
val jsonString = JSON.toJSONString(list)
val s = "原始json : $jsonString"
textView.text = s
s.log()
parse(jsonString, KItem::class.java)
parse(jsonString, JItem1::class.java)
parse(jsonString, JItem2::class.java)
}
private fun parse(jsonString: String, clazz: Class<out Any>) {
val items = try {
JSON.parseArray(jsonString, clazz)
} catch (e: Exception) {
e.printStackTrace()
null
}
val s = "\n\n使用${clazz.simpleName}解析結(jié)果 : ${items?.toTypedArray()?.contentToString()}"
textView.append(s)
s.log()
}
private fun createTestData(): List<KItem> {
val mutableList = mutableListOf<KItem>()
mutableList.add(KItem(0, "張111"))
mutableList.add(KItem(1, "王222"))
return mutableList
}
data class KItem @JSONCreator constructor(var id: Int? = null, var name: String? = null) {
override fun toString(): String = "{name =$name,id =$id}"
}
class JItem1 {
var id: Int = 0
var name: String = ""
override fun toString(): String = "{name =$name,id =$id}"
}
class JItem2 @JSONCreator constructor(var id: Int = 0, var name: String = "") {
override fun toString(): String = "{name =$name,id =$id}"
}
private fun String.log() {
Log.e("Test", this)
}
}