如何使用 Gson lib 将 Scala 集合列表序列化为 json

How to serialize a Scala Collection List into json using Gson lib

我有一个名为 Inbox 的 class,其中包含一个 Int 和一个 MessagesListMessage 是另一个 class。

问题是我想在 MongoDB 中存储 Inbox class 的对象。我必须序列化这些对象,所以我使用 Gson,但它在反序列化时抛出异常。

java.lang.RuntimeException: Failed to invoke public scala.collection.immutable.List() with no args

这里是 Inbox class :

@SerialVersionUID(1)
class Inbox(val uuid: Int, var messageList: ListBuffer[Message]) extends Serializable {
  addUuidToList(uuid)      

  /*
   * Auxiliary Constructor
   */
  def this() {
    this(0, ListBuffer[Message]())
  }

  def addToMessageList(addMessage: Message) = {
    messageList += addMessage
  }

  var IdList = new MutableList[Int]()

  def addUuidToList(uuid : Int)  = {
    IdList += uuid   
  }

  /*
   * Getters
   */
  def getUuid: Int = uuid

  /*
   * Returns sorted List based on dateTime attribute of the Message Class
   */
  def getMessageList : ListBuffer[Message] = {
    //var sortedList = messageList.sorted
    messageList
  }

  def getUuidsList: MutableList[Int] = IdList
}

Message class :

class Message(
  val uuid: Int,
  val subject: String,
  val body: String, 
  var artworkUuid: Int,
  val dateTime: LocalDateTime = LocalDateTime.now()
) extends Ordered[Message] with Serializable

我的 Test 申请:

object Test extends App {
  val inbox = new Inbox(333,messageList)

  val gson = new Gson()
  val g = gson.toJson(inbox)
  println(g + " converting to json")
  var inboxObj = gson.fromJson(g, classOf[Inbox])
  println("message object returned is " + inboxObj)   
}

控制台打印的输出:

{"uuid":333,"messageList":{"scala$collection$mutable$ListBuffer$$start":{},"last0":{"head":{"uuid":321,"subject":"subject1","body":"bodyText1","artworkUuid":101,"dateTime":{"date":{"year":2015,"month":7,"day":14},"time":{"hour":11,"minute":6,"second":51,"nano":579000000}},"readStatusInt":0,"delete":{"deleteStatusInt":1,"deleteReasonInt":1}},"tl":{}},"exported":false,"len":2},"IdList":{"first0":{"elem":333,"next":{}},"last0":{"elem":333,"next":{}},"len":1}}converting to  json
[error] (run-main-0) java.lang.RuntimeException: Failed to invoke public scala.collection.immutable.List() with no args
java.lang.RuntimeException: Failed to invoke public scala.collection.immutable.List() with no args
    at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:107)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.read(ReflectiveTypeAdapterFactory.java:103)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.read(ReflectiveTypeAdapterFactory.java:103)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.Gson.fromJson(Gson.java:810)
    at com.google.gson.Gson.fromJson(Gson.java:775)
    at com.google.gson.Gson.fromJson(Gson.java:724)
    at com.google.gson.Gson.fromJson(Gson.java:696)
    at TestActor$.delayedEndpoint$TestActor(TestActor.scala:307)
    at TestActor$delayedInit$body.apply(TestActor.scala:54)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main.apply(App.scala:76)
    at scala.App$$anonfun$main.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:383)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at TestActor$.main(TestActor.scala:54)
    at TestActor.main(TestActor.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
Caused by: java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:104)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.read(ReflectiveTypeAdapterFactory.java:103)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.read(ReflectiveTypeAdapterFactory.java:103)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.Gson.fromJson(Gson.java:810)
    at com.google.gson.Gson.fromJson(Gson.java:775)
    at com.google.gson.Gson.fromJson(Gson.java:724)
    at com.google.gson.Gson.fromJson(Gson.java:696)

可能是ListBuffer的问题我在java.util之前转换成List,试试这个代码:

import scala.collection.JavaConverters._
import scala.collection.mutable.ListBuffer
import com.google.gson.Gson
import java.util.ArrayList
import java.lang.reflect.Type
import com.google.gson.reflect.TypeToken 

object GSONinScala extends App {


  var id=4

  var fruits = new ListBuffer[String]()

  fruits += "Apple"
  fruits += "Banana"
  fruits += "Orange"


  val tmp : Inbox = Inbox(id, fruits)

  val json = tmp.toJson()

  println("Object2json: " + json)

}

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
import com.google.gson.Gson
import java.util.ArrayList
import com.google.gson.annotations.Expose;
import java.util.{List => JavaList}

case class Inbox(uuid:Int,@Expose(deserialize = false) messageList:ListBuffer[String]) {

  val msgList:JavaList[String] = messageList

  def toJson() = new Gson().toJson(this)

}

我得到这个输出

[info] Running GSONinScala 
Object2json: {"uuid":4,"messageList":{"scala$collection$mutable$ListBuffer$$start":{},"last0":{"head":"Orange","tl":{}},"exported":false,"len":3},"msgList":["Apple","Banana","Orange"]}
[success] Total time: 2 s, completed 14-jul-2015 11:07:16

希望对您有所帮助