使用Scala中的Gson序列化/反序列化案例对象

时间:2015-08-10 19:59:38

标签: scala gson

我正在使用Gson序列化和反序列化对象,并将结果保存在Redis中。即将对象序列化为json字符串然后放入Redis,当对象被检索时,它是字符串然后我使用Gson.fromjson(str,className)反序列化为对象。

我是Scala的初学者,所以我认为我的用法不正确。

我有以下课程:

case class Status(id: String, state: State)

其中State如下:

sealed trait State {}

case object COMPLETED_SUCCESSFULLY extends State {}

case object FINISHED_POLLING extends State {}

case object CURRENTLY_DOWNLOADING extends State {}

case object FINISHED_DOWNLOADING extends State {}

case object CURRENTLY_UPLOADING extends State {}

case object FINISHED_UPLOADING extends State {}

我想将Status序列化为json字符串,然后将其反序列化为对象。

但是,当我使用Gson序列化Status时,我得到:

"{\"id\":\"foo\",\"state\":{}}"

为什么?

例如:

val Status = new Status("foo", COMPLETED_SUCCESSFULLY)

我希望序列化输出为

"{\"id\":\"foo\",\"state\":\"COMPLETED_SUCCESSFULLY\"}"

1 个答案:

答案 0 :(得分:5)

默认情况下, Gson 将case对象序列化为空json对象:{}。您必须编写自定义序列化程序以获得预期的行为:

object StateSerializer extends JsonSerializer[State] {
  override def serialize(t1: State, t2: Type, jsonSerializationContext: JsonSerializationContext): JsonElement = {
    val res = new JsonObject()
    res.add("name", new JsonPrimitive(t1.toString))
    res
  }
}


val gson = new GsonBuilder().registerTypeHierarchyAdapter(classOf[State], StateSerializer)
.registerTypeHierarchyAdapter(classOf[State], StateDeserializer).setPrettyPrinting().create()

println(gson.toJson(COMPLETED_SUCCESSFULLY))  

将打印:

{
  "name": "COMPLETED_SUCCESSFULLY"
}

此外,如果您想将json转换为case对象,则必须实现JsonDeserializer

object StateDeserializer extends JsonDeserializer[State] {
  override def deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): State = {
    val res = json match {
      case o: JsonObject if o.has("name") && o.entrySet().size() == 1 =>
        val name = o.get("name").getAsString
        name match {
          case "FINISHED_POLLING" => FINISHED_POLLING
          case "FINISHED_DOWNLOADING" => FINISHED_DOWNLOADING
          case "FINISHED_UPLOADING" => FINISHED_UPLOADING
          case "CURRENTLY_DOWNLOADING" => CURRENTLY_DOWNLOADING
          case "CURRENTLY_UPLOADING" => CURRENTLY_UPLOADING
          case "COMPLETED_SUCCESSFULLY" => COMPLETED_SUCCESSFULLY
          case _ => null
        }
      case _ => null
    }

    Option(res).getOrElse(throw new JsonParseException(s"$json can't be parsed to State"))
  }
}

println(gson.fromJson("{\"name\": \"COMPLETED_SUCCESSFULLY\"}", classOf[State])) 

将打印:

COMPLETED_SUCCESSFULLY
相关问题