2017-11-08 15 views
1

포함하는 엔티티에 대해 json 형식을 쓰려고합니다. 옵션의지도.play.api.libs.json.Format의 인스턴스가 scala.Predef.Map [Java.String [scala.Option [scala.Double]]에 사용 가능하지 않습니다.

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

val a: Map[String, Option[Double]] = Map("a" -> None) 

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

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

Json.toJson(Person(a)) 

답변

2

당신은 정의 할 수 있습니다 implicits은 :

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 기준으로합니다.

+0

None 값을 0.0으로 매핑하면 유효한 값이 될 수 있으므로 좋은 해결책이 아닐 수도 있습니다. 없음은 null에 매핑되어야합니다. –

+0

암시 적 쓰기에 다음과 같이 변경하면 이제 없음에 대해 null이 반환됩니다. JsObject (map.mapValues ​​{ case None => JsNull ) Some (x) => JsNumber (x) }' –

+0

@ SuhitKamthe 네, 이것은 그러한 함축을 정의하는 방법의 예입니다. –

0
문제는 중첩 된 형태 변수 작업을 플레이 JSON 매크로 못하는 것 같다

:

Map[String, Option[Double]]

당신이 오류

Error:(8, 68) No instance of play.api.libs.json.Format is available for scala.Predef.Map[java.lang.String, scala.Option[scala.Double]] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)

코드 다음 발생 중간 유형 랩핑을 사용할 수 있음 Option

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)) 

또 다른 옵션은 포맷터를 직접 작성하는 것입니다.