如何将Map [CustomType,String]序列化为JSON

如何将Map [CustomType,String]序列化为JSON

问题描述:

给出以下Enumeration ...

object MyEnum extends Enumeration {

  type MyEnum = Value

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

import MyEnum._

...以及以下Map ...

... and the following Map...

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

...我需要将m转换为JSON:

... I need to transform m to JSON:

import play.api.libs.json._

val js = Json.toJson(m)

由于编译器找不到类型为scala.collection.immutable.Map[MyEnum.Value,String]的Json序列化器,因此最后一条语句无法编译.

The last statement doesn't compile because the compiler doesn't find a Json serializer for type scala.collection.immutable.Map[MyEnum.Value,String].

问题:由于Play确实提供了类型scala.collection.immutable.Map[String,String]的序列化程序,并且我的枚举实际上包含字符串,因此有没有办法重用默认的JSON序列化程序?

Question: Since Play does provide a serializer for type scala.collection.immutable.Map[String,String], and my enumeration actually contains strings, is there a way to reuse the default JSON serializer?

The built-in Reads objects don't define a Reads for a Map that's parametric in the key. You could do something like:

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

使用上面的值,您将得到:

And with your values above, you get:

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

如果愿意,可以加紧A上的界限,使其不适用于任何AnyRef.

If you want to, you can tighten those bounds on A to make it not applicable to any AnyRef.