json - 玩 - 尝试实现写入列表[任何]

标签 json scala playframework playframework-2.0

我有一个如下所示的案例类:

案例类 A(名称:String,值:List[Any]) 而值可以是长列表或字符串。

我正在尝试实现写入但没有成功。 这是我的代码:

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

出于某种原因,当我尝试使用以下值编写案例类时:

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指出的那样,通用类型将被删除。

在这种情况下,我会使用 collectList[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 通常是一个好主意。

关于json - 玩 - 尝试实现写入列表[任何],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35834218/

相关文章:

playframework - 如何在 Play Framework 2.5 上测试表单?

json - 在 Play 中将 Seq 映射到 JSON

json - Jackson @JsonView 没有按预期工作

javascript - 使用复杂的 JSON 填充嵌套的 ng-repeat

java - 将 Sonar、Jacoco、Gradle、ScalaTest 与 Junit、Java 集成

java - 使用 RxJava (ReactiveX) 运行 Observable 需要多长时间?

c# - MVC-Web API : 405 method not allowed

c++ - 如何在不使用 json 的情况下解析 Qt C++ 中的数据?

scala - 如何将任何数字转换为长整数

java - 访问 PlayFramework 中的 HTTP 上下文