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

在Scala中使用Gson序列化/反序列化案例对象,scala,gson,Scala,Gson,我正在使用Gson序列化和反序列化对象,并将结果保存在Redis中。ie对象被序列化为json字符串,然后放入Redis,当对象被检索时,它是字符串,然后我使用Gson.fromjson(str,className)反序列化为对象 我是Scala的初学者,所以我认为我的用法不正确 我有以下课程: case class Status(id: String, state: State) 其中状态为: sealed trait State {} case object COMPLETED_SUCC

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

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

我有以下课程:

case class Status(id: String, 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 {}
我想将
状态
序列化为一个json字符串,然后将其反序列化回一个对象

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

"{\"id\":\"foo\",\"state\":{}}"
为什么呢

例:

我希望序列化的输出是

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

默认情况下,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"
}
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])) 
将打印:

{
  "name": "COMPLETED_SUCCESSFULLY"
}
COMPLETED_SUCCESSFULLY

您希望得到什么样的输出?@ka4eli更新了问题。我只希望能够使用gson进行序列化和反序列化。这是否意味着我必须为我拥有的每个枚举编写序列化程序?此外,对于反序列化,我不能只执行gson。fromJson(String,classOf[Status])更新了答案。现在,所有状态都有一个序列化程序。是的,你不能。因为Gson不知道这个
{“name”:“COMPLETED_SUCCESSFULLY”}
对应于
COMPLETED_SUCCESSFULLY
。生活很艰难。。。根据我在上面发布的信息,是否还有其他方法可以做到这一点?将值对象转换为放入redis中的字符串,然后稍后从redis提取并解析/反序列化为值对象?我不完全确定,如果密封的特点是正确的方式去…与反序列化更新的答案。现在你可以做任何事了)