如何为通用json-spray解析器定义层次结构?

时间:2017-09-10 02:37:03

标签: scala spray-json

我们的API在响应中始终包含substrn("wooloomooloo", "oo")total-count,但entities的类型不同。我想要做的就是进行解析和解析。转换为案例类更通用。

尝试使用以下类型

entities

以下示例:

case class StandardReturn[A](
    `total-count`: Double,
    entities: List[A]
)

case class System(
    id: String,
    name: String
)

这是可以理解的给我

object SystemProtocol extends DefaultJsonProtocol {
  implicit val systemFormat: RootJsonFormat[System] = 
    jsonFormat2(System)
  implicit def entityFormat[A: JsonFormat] =
    jsonFormat(StandardReturn.apply[A], "total-count", "entities")
}
import SystemProtocol._

val response = """{
  "total-count": 10,
  "entities": [
    { "id": "1", "name": "me" }
  ]
}"""

class Example {
  def transform[A: JsonReader](entityString: String) =
    entityString.parseJson
      .convertTo[A]
      .entities  // Where I'm running into trouble
}
object Example {
  val transformed = new Example().transform[StandardReturn[System]](response)
}
Example.transformed

如何设置案例类/类型,以便{?}}确保Error:(34, 42) value entities is not a member of type parameter A entityString.parseJson.convertTo[A].entities // Where I'm running into trouble ^ 在转换为transform类型后始终存在entities A { {1}})?我对scala的类型系统不太熟悉,谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

在您的代码中,类型参数A除了绑定到JsonReader的上下文(类型为JsonReader[A]的隐式参数)之外没有边界。因此,正如您已经提到的,A可以是任何内容,因此您无法调用entities方法。如果您转换为StandardReturn[A]而非A,则会解决此问题。

def transform[A: JsonReader](entityString: String) =
  entityString.parseJson
    .convertTo[StandardReturn[A]] <- just convert to what you actually want
    .entities

此外,您必须将new Example().transform[StandardReturn[System]](response)中的类型参数替换为System而不是StandardReturn[System],因为上述方法已更改。

编译器现在需要类型为JsonReader[StandardFormat[System]]的隐式参数。但在隐式范围内,只有systemFormat类型为JsonReader[System](在SystemProtocol中)。编译器还没有放弃:他试图找到从JsonReader[System]JsonReader[StandardFormat[System]]的隐式转换,这只是您定义的方法entityFormat。呀!

最后一句话:如果entityFormat替换jsonFormat(StandardReturn.apply[A], "total-count", "entities"),您可以进一步简化方法jsonFormat2(StandardReturn.apply[A]),如documentation中所述。