Json 播放-尝试实现写入列表[任何]
我有一个case类,如下所示: 案例类别A(名称:字符串,值:列表[任何]) 而值可以是长字符串或字符串的列表 我正在尝试实现一个写操作,但没有成功。 这是我的代码:Json 播放-尝试实现写入列表[任何],json,scala,playframework,playframework-2.0,Json,Scala,Playframework,Playframework 2.0,我有一个case类,如下所示: 案例类别A(名称:字符串,值:列表[任何]) 而值可以是长字符串或字符串的列表 我正在尝试实现一个写操作,但没有成功。 这是我的代码: implicit val myWrites: Writes[A] = ( (JsPath \ "name").write[String] and (JsPath \ "values").write[JsArray].contramap[List[Any]]( (list: List[Any]) => list m
implicit val myWrites: Writes[A] = (
(JsPath \ "name").write[String] and
(JsPath \ "values").write[JsArray].contramap[List[Any]](
(list: List[Any]) => list match{
case longs: List[Long] => JsArray(longs.map(l => JsNumber(l)))
case strings: List[String] => JsArray(strings.map(s => JsString(s)))
})
) (unlift(A.unapply))
出于某种原因,当我试图用以下值编写case类时:
A("name", List("val1", "val2"))
我得到以下例外情况:
java.lang.String cannot be cast to java.lang.Long
java.lang.ClassCastException: java.lang.String cannot be cast to
java.lang.Long
at scala.runtime.BoxesRunTime.unboxToLong(BoxesRunTime.java:105)
它在第一个case行失败:case longs:List[Long]
我不确定我做错了什么。有什么想法吗
谢谢 非常接近,但请记住,当您说
List[Any]
时,就类型系统而言,列表值可能是异构的,正如@m-z指出的,泛型类型将被删除
在这种情况下,我会使用collect
将List[Any]
转换为List[JsValue]
以丢弃任何不是字符串或长字符串的内容:
case class A(name: String, values: List[Any])
implicit val myWrites: Writes[A] = (
(JsPath \ "name").write[String] and
(JsPath \ "values").write[List[JsValue]].contramap[List[Any]](
_.collect {
case str: String => JsString(str)
case long: Long => JsNumber(long)
})
)(unlift(A.unapply))
我最近不得不做一些类似的事情来处理一个接受异构JSON数组的web服务,但通常最好避免在Scala级别使用
Any
。对解决方案的另一个建议:
implicit val myWrites: Writes[A] = (
(JsPath \ "name").write[String] and
(JsPath \ "values").write[JsArray].contramap[List[Any]](
case l if l.isEmpty => JsArray(Seq())
case list@List(_: Long, _*) => JsArray(list.map(l => JsNumber(l.asInstanceOf[Long])))
case list@List(_: String, _*) => JsArray(list.map(s => JsString(s.asInstanceOf[String])))
) (unlift(A.unapply))
List
的类型参数在运行时被删除,因此无论包含的类型是什么,longs:List[Long]
都将匹配。为什么您需要一个列表[Any]
?注意这一点,因为如果您的列表同时包含字符串和long(类型系统将允许),它将在运行时失败,出现ClassCastException
。同意-我假设同一列表中不会有多个类型。