JSON scala 中的反序列化 - 如果字段不存在则使用默认值
JSON deserialization in scala - use default value if field doesn't exist
我在 scala 中将 json 反序列化为 class。
如果 class 有一个 json 中不存在的成员,我希望它获得在主构造函数中分配的默认值,但事实并非如此。
在下面的例子中,我怎样才能让 prop2 成为一个空字符串(现在它是空的)。
import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
case class Thing(var prop1 : String = "",
var prop2 : String = "",
var prop3 : String = "")
object test {
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
def main(args: Array[String]): Unit = {
val thingStr = """{"prop1":"val1","prop3":"val3"}"""
val thing = mapper.readValue[Thing](thingStr)
System.out.println(thing)
}
}
以上代码打印
Thing(val1,null,val3)
如何让 prop2 为空字符串?
我最终按照 Diego 的建议编写了一个自定义反序列化器。
import com.fasterxml.jackson.core.{Version, JsonParser, JsonGenerator}
import com.fasterxml.jackson.databind._
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
case class Thing(var prop1 : String = "",
var prop2 : String = "",
var prop3 : String = "")
object test {
val module = new SimpleModule("CustomJson", Version.unknownVersion())
module.addDeserializer(classOf[Thing], new ThingDeserializer)
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
mapper.registerModule(module)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
def main(args: Array[String]): Unit = {
val thingStr = """{"prop1":"val1","prop3":"val3"}"""
val thing = mapper.readValue[Thing](thingStr)
System.out.println(thing)
}
}
class ThingDeserializer extends JsonDeserializer[Thing] {
def deserialize(jp: JsonParser, context: DeserializationContext) = {
val node : JsonNode = jp.getCodec().readTree(jp);
System.out.println(node)
new Thing(prop1 = if (node.has("prop1")) node.get("prop1").toString else "",
prop2 = if (node.has("prop2")) node.get("prop2").toString else "",
prop3 = if (node.has("prop3")) node.get("prop3").toString else "")
}
}
我在 scala 中将 json 反序列化为 class。 如果 class 有一个 json 中不存在的成员,我希望它获得在主构造函数中分配的默认值,但事实并非如此。
在下面的例子中,我怎样才能让 prop2 成为一个空字符串(现在它是空的)。
import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
case class Thing(var prop1 : String = "",
var prop2 : String = "",
var prop3 : String = "")
object test {
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
def main(args: Array[String]): Unit = {
val thingStr = """{"prop1":"val1","prop3":"val3"}"""
val thing = mapper.readValue[Thing](thingStr)
System.out.println(thing)
}
}
以上代码打印
Thing(val1,null,val3)
如何让 prop2 为空字符串?
我最终按照 Diego 的建议编写了一个自定义反序列化器。
import com.fasterxml.jackson.core.{Version, JsonParser, JsonGenerator}
import com.fasterxml.jackson.databind._
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
case class Thing(var prop1 : String = "",
var prop2 : String = "",
var prop3 : String = "")
object test {
val module = new SimpleModule("CustomJson", Version.unknownVersion())
module.addDeserializer(classOf[Thing], new ThingDeserializer)
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
mapper.registerModule(module)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
def main(args: Array[String]): Unit = {
val thingStr = """{"prop1":"val1","prop3":"val3"}"""
val thing = mapper.readValue[Thing](thingStr)
System.out.println(thing)
}
}
class ThingDeserializer extends JsonDeserializer[Thing] {
def deserialize(jp: JsonParser, context: DeserializationContext) = {
val node : JsonNode = jp.getCodec().readTree(jp);
System.out.println(node)
new Thing(prop1 = if (node.has("prop1")) node.get("prop1").toString else "",
prop2 = if (node.has("prop2")) node.get("prop2").toString else "",
prop3 = if (node.has("prop3")) node.get("prop3").toString else "")
}
}