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

iCo*_*unk 2 scala gson

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

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

我有以下课程:

case class Status(id: String, state: State)
Run Code Online (Sandbox Code Playgroud)

国家如下:

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 {}
Run Code Online (Sandbox Code Playgroud)

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

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

"{\"id\":\"foo\",\"state\":{}}"
Run Code Online (Sandbox Code Playgroud)

这是为什么?

例如:

val Status = new Status("foo", COMPLETED_SUCCESSFULLY)
Run Code Online (Sandbox Code Playgroud)

我希望序列化的输出是

"{\"id\":\"foo\",\"state\":\"COMPLETED_SUCCESSFULLY\"}"
Run Code Online (Sandbox Code Playgroud)

ka4*_*eli 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))  
Run Code Online (Sandbox Code Playgroud)

将打印:

{
  "name": "COMPLETED_SUCCESSFULLY"
}
Run Code Online (Sandbox Code Playgroud)

此外,如果您想将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])) 
Run Code Online (Sandbox Code Playgroud)

将打印:

COMPLETED_SUCCESSFULLY
Run Code Online (Sandbox Code Playgroud)