没有play.api.libs.json.Format的实例可用于scala.Predef.Map [java.lang.String,scala.Option [scala.Double]]

时间:2017-11-08 11:16:29

标签: json scala playframework play-json

尝试为包含Option of Map的实体编写json格式。它抛出以下错误

  

错误:(8,68)没有play.api.libs.json.Format的实例可用于隐式范围内的scala.Predef.Map [java.lang.String,scala.Option [scala.Double]] (提示:如果在同一个文件中声明,请确保之前已声明)

代码段:

https://www.instagram.com/anyuser/media

2 个答案:

答案 0 :(得分:2)

您可以定义含义:

  import scala.collection.Map

  object Person {
    implicit object MapReads extends Reads[Map[String, Option[Double]]] {
      def reads(jsValue: JsValue): JsResult[Map[String, Option[Double]]] = jsValue match {
        case JsObject(map) => JsSuccess(
          map.mapValues {
            case JsNumber(d) => Some(d.toDouble)
            case _ => None
          }
        )
        case _ => JsError()
      }
    }

    implicit object MapWrites extends Writes[Map[String, Option[Double]]] {
      def writes(map: Map[String, Option[Double]]): JsValue =
        JsObject(map.mapValues(optd => JsNumber(optd.getOrElse[Double](0.0))))
    }

    implicit val personFormat: OFormat[Person] = Json.format[Person]
  }

  println(Json.toJson(Person(a)))//{"x":{"a":0}}

基于answer

答案 1 :(得分:0)

问题似乎是play-json宏无法使用嵌套类型变量:

Map[String, Option[Double]]

您可以使用中间类型换行选项

import play.api.libs.json.{Json, OFormat}

case class OptionDouble(value: Option[Double])
case class Person(x: Map[String, OptionDouble])

implicit val optionDoubleFormat = Json.format[OptionDouble]
implicit val personFormat = Json.format[Person]

val a: Map[String, OptionDouble] = Map("a" -> OptionDouble(None))
Json.toJson(Person(a))

另一种选择可能是手工编写格式化程序。