3

以下を考えるとEnumeration...

object MyEnum extends Enumeration {

  type MyEnum = Value

  val Val1 = Value("val1")
  val Val2 = Value("val2")
  val Val3 = Value("val3")
} 

import MyEnum._

...そして以下Map...

val m = Map(
  val1 -> "one",
  val2 -> "two",
  val3 -> "three"
)

... mJSON に変換する必要があります。

import play.api.libs.json._

val js = Json.toJson(m)

コンパイラが type の Json シリアライザーを見つけられないため、最後のステートメントはコンパイルされませんscala.collection.immutable.Map[MyEnum.Value,String]

質問: Play は type のシリアライザーを提供してscala.collection.immutable.Map[String,String]おり、私の列挙には実際に文字列が含まれているため、デフォルトの JSON シリアライザーを再利用する方法はありますか?

4

2 に答える 2

6

組み込みReadsオブジェクトは、キーでパラメトリックなReadsfor を定義しません。Map次のようなことができます:

implicit def looserMapWrites[A <: AnyRef, B : Writes]: Writes[Map[A, B]] = Writes { o => 
  Json.toJson(o.map { case (key, value) => 
    key.toString -> value 
  })(Writes.mapWrites) 
}

上記の値を使用すると、次のようになります。

scala> Json.toJson(m)(looserMapWrites)
res1: play.api.libs.json.JsValue = {"val1":"one","val2":"two","val3":"three"}

必要に応じて、これらの境界を引き締めて、Aどの にも適用されないようにすることができますAnyRef

于 2014-09-18T05:14:41.503 に答える
1

列挙型を文字列表現との間で変換する MyEnum.Value の play.api.libs.json.Format を定義する必要があります。次のような:

import play.api.libs.json._

object MyEnum extends Enumeration {

  type MyEnum = Value

  val Val1 = Value("val1")
  val Val2 = Value("val2")
  val Val3 = Value("val3")

  implicit val myEnumWrites = new Writes[Value]{
    def writes(o:Value)=JsString(o.toString)
  }
} 

MyEnum のより完全な形式 (読み書き) は次のようになります。

implicit val myEnumFormat = new Format[Value]{
  def writes(o:Value)=JsString(o.toString)
  def reads(json:JsValue):JsResult[Value]=json match {
    case JsString("val1") =>JsSuccess(Val1)
    case JsString("val2") =>JsSuccess(Val2)
    case JsString("val3") =>JsSuccess(Val3)
    case other => JsError(s"$other is not a valid value for MyEnum")
  }
}

列挙の使用はお勧めしません。一般に、封印された特性とケース オブジェクト/ケース クラスの階層、または Java 列挙を使用して置き換えることができます。

于 2014-09-17T19:55:04.427 に答える