繁体   English   中英

Jackson scala模块:反序列化案例object枚举

[英]Jackson scala module: deserialize case object enumeration

我正在使用 Jackson scala 模块,我需要序列化/反序列化案例 object 枚举。 序列化工作正常,但是当反序列化返回值时,我得到com.fasterxml.jackson.databind.exc.InvalidDefinitionException 有办法让它工作吗? 我想避免使用“经典”scala 枚举,因为我将失去定义枚举层次结构的能力。

用于测试的代码:

import com.fasterxml.jackson.annotation.JsonValue
import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper


sealed trait Operations { @JsonValue def jsonValue: String }

case object Foo extends Operations { override def jsonValue: String = "Foo" }

case object Bar extends Operations { override def jsonValue: String = "Bar" }


sealed trait RichOperations extends Operations

case object Baz extends RichOperations { override def jsonValue: String = "Baz" }


object JsonUtils extends App {

  val jsonMapper = new ObjectMapper() with ScalaObjectMapper
  jsonMapper.registerModule(DefaultScalaModule)
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

  def toJson(value: Any): String = jsonMapper.writeValueAsString(value)

  def fromJson[T: Manifest](json: String): T = jsonMapper.readValue[T](json)


  println(toJson(Foo)) // "Foo"
  println(toJson(Bar)) // "Bar"
  println(toJson(Baz)) // "Baz"
  println(fromJson[Operations](toJson(Foo))) // throws InvalidDefinitionException
  println(fromJson[Operations](toJson(Bar)))
  println(fromJson[RichOperations](toJson(Baz)))
}

我解决了定义自定义反序列化器的问题。

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}


class OperationsDeserializer extends JsonDeserializer[Operations] {

  override def deserialize(p: JsonParser, ctxt: DeserializationContext): Operations = {
    p.getValueAsString match {
      case Foo.jsonValue => Foo
      case Bar.jsonValue => Bar
      case value => throw new IllegalArgumentException(s"Undefined deserializer for value: $value")
    }
  }
}


class RichOperationsDeserializer extends JsonDeserializer[Operations] {

  override def deserialize(p: JsonParser, ctxt: DeserializationContext): Operations = {
    p.getValueAsString match {
      case Foo.jsonValue => Foo
      case Bar.jsonValue => Bar
      case Baz.jsonValue => Baz
      case value => throw new IllegalArgumentException(s"Undefined deserializer for value: $value")
    }
  }
}

此外,由于在匹配/案例中需要稳定的标识符,我将jsonValuedef更改为val :不幸的是,这需要在 object 枚举的每种情况下声明@JsonValue注释。

import com.fasterxml.jackson.databind.annotation.JsonDeserialize


@JsonDeserialize(using = classOf[OperationsDeserializer])
sealed trait Operations { val jsonValue: String }

case object Foo extends Operations { @JsonValue override val jsonValue: String = "Foo" }

case object Bar extends Operations { @JsonValue override val jsonValue: String = "Bar" }


@JsonDeserialize(using = classOf[RichOperationsDeserializer])
sealed trait RichOperations extends Operations

case object Baz extends RichOperations { @JsonValue override val jsonValue: String = "Baz" }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM