我正在使用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\"}"
答案 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