fastjson 解析kotlin class/data class的正确姿势

众所周知,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) {
     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 {
     val mutableList = mutableListOf()
     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)
 }
 }

你可能感兴趣的:(fastjson 解析kotlin class/data class的正确姿势)