scala中的JSON反序列化 - 如果字段不存在,则使用默认值

时间:2015-03-19 07:10:41

标签: json scala jackson

我将json反序列化为scala中的类。 如果该类有一个json中不存在的成员,我希望它能获得在主构造函数中指定的默认值,但事实并非如此。

在下面的例子中,我怎样才能让prop2成为一个空字符串(现在它是null)。

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成为一个空字符串?

1 个答案:

答案 0 :(得分:1)

我最终按照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 "")
  }
}