您是否尝试过使用案例类反序列化?
https://github.com/FasterXML/jackson-module-scala/blob/master/src/test/scala/com/fasterxml/jackson/module/scala/deser/CaseClassDeserializerTest.scala
如果这不起作用,我认为您最好创建提取器来表示您的域对象。下面的代码假设一个 scala Map,但它应该给你一个想法。不需要隐式转换。
case class DomainObjectA(v1: String, v2: String)
object DomainObjectAExtractor {
def unapply(m: Map[String, String]) = for {
v1 <- m.get("key1")
v2 <- m.get("key2")
} yield DomainObjectA(v1, v2)
}
case class DomainObjectB(v3, v4, v5)
object DomainObjectBExtractor {
def unapply(m: Map[String, String]) = for {
v3 <- m.get("key3")
v4 <- m.get("key4")
v5 <- m.get("key5")
} yield DomainObjectB(v3, v4, v5)
}
json match {
case DomainObjectAExtractor(a@DomainObjectA(_, _)) => a
case DomainObjectBExtractor(b@DomainObjectB(_, _, _)) => b
}
但是,如果您坚持尝试匹配键/值对,则可能有一些方法可以完成您可以接受的事情。无法将输入从 传递到 unapply 函数case
,如果我理解您想要正确执行的操作,我认为这将是必需的。可以使用即将正式发布的 scala 2.10 中的实验性宏来执行此操作。我和他们玩得还不够多,不知道这是否可能。
如果假设键的顺序,您可以想出一个::
类似于::
for list 的 unapply 运算符。这可以K, V
以这个已知的顺序提取对。就我个人而言,这对我的口味来说太脆弱了。
val json = Map(("key1" -> "one"), ("key2" -> "two"))
object -> {
def unapply[A, B](ab: (A, B)) = Some(ab)
}
object :: {
def unapply[K, V](m: Map[K, V]): Option[((K, V), Map[K, V])] =
m.headOption.map(_ -> m.tail)
}
scala> json match {
| case ("key1" -> "one") :: ("key2" -> value2) :: _ => value2
| }
res0: java.lang.String = two
您将无法以错误的顺序提取密钥
scala> json match {
| case ("key2" -> value2) :: _ => value2
| case _ => "match fail"
| }
res2: java.lang.String = match fail
你也可以写Key1
, Key2
, Key3
。这可能会或可能不会很好地扩展。
object && {
def unapply[A](a: A) = Some((a, a))
}
object Key2 {
def unapply[V](m: Map[String, V]) = m.get("key2")
}
object Key1 {
def unapply[V](m: Map[String, V]) = m.get("key1")
}
scala> json match {
| case Key2(value2) && Key1(value1) => (value2, value1)
| }
res5: (java.lang.String, java.lang.String) = (two,one)