从Circe创建Json对象,其值可以是String或List

时间:2017-10-04 09:19:48

标签: scala circe

我想创建一个带有circe的Json对象,其值可以是String或List,如:

val param = Map[String, Map[String, Object]](
    "param_a" -> Map[String, Object](
      "param_a1" -> "str_value",
      "param_a2" -> List(
        Map[String, String](
          "param_a2.1" -> "value_2.1",
          "param_a2.2" -> "value_2.2")
      )
    ),

然而,如果我这样做

    param.asJson

失败了

    Error:(61, 23) could not find implicit value for parameter encoder: io.circe.Encoder[scala.collection.immutable.Map[String,Map[String,Object]]]
  .postData(param.asJson.toString().getBytes)

2 个答案:

答案 0 :(得分:1)

好的,快速修复是使用Map [String,Json]

val param = Map[String, Map[String, Json]](
"param_a" -> Map[String, Json](
  "param_a1" -> "str_value".asJson,
  "param_a2" -> List(
    Map[String, String](
      "param_a2.1" -> "value_2.1",
      "param_a2.2" -> "value_2.2")
  ).asJson
),

答案 1 :(得分:0)

您只需要在0 3 2 1 的范围内提供Encoder的隐式实例。试试这个:

Object

但是我会避免使用implicit val objEncoder: Encoder[Object] = Encoder.instance { case x: String => x.asJson case xs: List[Map[String, String]] => xs.asJson } 而是提供一个ADT来包装两个可能的情况,即ObjectString,但这取决于你。此外,在Scala世界中,List[Map[String, String]]更广为人知的是Object,因此,如果您只想使用AnyRef,我建议您将其称为Object

P.S。:如果您使用的是Scala版本> = 2.12.0,则可以通过SAM conversion in overloading resolution来避免输入AnyRef。所以代码将成为:

Encoder.instance