众所周知,java bean的写法会影响fastjson的解析,那么当使用kotlin的时候怎么写bean类才能保证fastjson能够正常的工作不挖坑呢?
分两种情况:
一、使用kotlin-reflect库
以下写法使用标准库和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整个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标准库
只有JItem1可以解析(实质上此种写法在本文测试的几种情况下都是可以的)
class JItem1 {
var id: Int = 0
var name: String = ""
override fun toString(): String = "{name =$name,id =$id}"
}
必要的配置
- proguard-rules.pro
#keep整个bean类
-keep class com.song.project.test.TestActivity$*{*;}
三 、总结:
- 使用kotlin-reflect库,
优点:一般写法都可以支持,通用性好
槽点: 需要额外依赖库,并且需要配置混淆 - 使用@JSONCreator
优点:使用方便
槽点:只有Android库可以生效
四、其他
- 测试版本:android专用库1.1.72/1.1.71 标准库 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}解析结果 : ${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)
}
}