我正在使用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)
默认情况下,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)
| 归档时间: |
|
| 查看次数: |
2593 次 |
| 最近记录: |