2017-11-12 17 views
0

を再生、レスポンスJSONは、このような形式を持っていますattributeValueのタイプはStringの値で、それ以外のときはBooleanの値です。ダイナミック型キャストが

私はタイプを動的に読むために私自身の読み込みと書き込みを書こうとしています。あなたは私のコメントで見ることができるよう

case class Data(attributeName: Option[String], attributeValue: Option[String], attributeSource: Option[String], attributeValueLabel: Option[String]) 

object Data{ 

    implicit val readsData: Reads[Data] = { 
    new Reads[Data] { 
     def reads(json: JsValue) = { 
     val attrValue = (json \ "attributeValue").as[] // How to cast to Boolean some time, but some other time is a String here 
     ...... 
     } 
    } 
    } 

だから、私はAPIの戻り値の型に(json \ "attributeValue")String/Booleanに、ベースをキャストする部分にこだわっています。これどうやってするの?

答えて

1

あなたはString最初にしてBooleanなどとして、それを解析しようとすることができます:

val strO = (json \ "attributeValue").asOpt[String] 
val value: Option[String] = strO match { 
    case [email protected](_) => str 
    case None  => (json \ "attributeValue").asOpt[Boolean].map(_.toString) 
} 
+0

やあ、答えに感謝しかし番目実際の型がブール型 – xtiger

+0

に固定されているため、構文解析のステップでは失敗します。あなたはどちらか一方を最初にチェックする必要があります –

1

あなたはさまざまな方法で属性を読み取ろうとしているときは、.orElse機能を使用することができます。

import play.api.libs.json.{JsPath, Json, Reads} 
import play.api.libs.functional.syntax._ 


val json1 = 
""" 
    |{ 
    | "attributeName": "some String", 
    | "attributeValue": false 
    |} 
""".stripMargin 

val json2 = 
    """ 
    |{ 
    | "attributeName": "some String", 
    | "attributeValue": "daily" 
    |} 
    """.stripMargin 

// I modified you case class to make the example short 
case class Data(attributeName: String, attributeValue: String) 
object Data { 

    // No need to define a reads function, just assign the value 
    implicit val readsData: Reads[Data] = (
    (JsPath \ "attributeName").read[String] and 

    // Try to read String, then fallback to Boolean (which maps into String) 
    (JsPath \ "attributeValue").read[String].orElse((JsPath \ "attributeValue").read[Boolean].map(_.toString)) 
)(Data.apply _) 
} 

println(Json.parse(json1).as[Data]) 
println(Json.parse(json2).as[Data]) 

出力:

Data(some String,false) 
Data(some String,daily)