2

这是我第二次碰到这个。编辑:我发现这也是我第二次在堆栈上询问,并且是我第三次或第四次遇到这个问题。其他问题在这里:Cast Class Exception in Scala: java.lang.Object to Scala CaseClass

大量编辑...经过大量分析,我可以简化问题。看来这是我如何使用特征和实现/覆盖 toJson 方法的问题......我确信这很容易,但我无法找到我做错了什么。

我得到了这个类转换异常,我看不出有什么问题。

我有这个:

package service

import play.api.libs.json.{JsObject, Json, JsValue}

/**
 * author: jason goodwin
 */
trait Jsonable{

  def toJson: JsValue = {null}
}

object Jsonable {
  def renderJsonableListToJson(entities: Iterable[Jsonable]): String = {

    val jsonList = Json.toJson(entities.map(x => x.toJson).toSeq)
    val result = JsObject("meta" -> JsObject(Seq()) :: "data" -> jsonList :: Nil)

    Json.stringify(result)
  }
}

这与java库接口:

trait GraphedArticle extends BaseFramedEntity with Jsonable {

  @Property("articleId")
  def setArticleId (userId: String)

  @Property("articleId")
  def getArticleId:String

  @Property("title")
  def setTitle (title: String)

  @Property("title")
  def getTitle:String

  @Property("preview")
  def setPreview (preview: String)

  @Property("preview")
  def getPreview: String

  @Property("imageUrl")
  def setImageUrl (imageUrl: String)

  @Property("imageUrl")
  def getImageUrl: String

  @Property("articleUrl")
  def setArticleUrl (imageUrl: String)

  @Property("articleUrl")
  def getArticleUrl: String

  override def toJson: JsValue = {
    val ret = JsObject(
      "articleId" -> Json.toJson(getArticleId)
        :: "graphId" -> Json.toJson(asVertex().getId.toString)
        :: "created_time" -> Json.toJson(123123123)
        :: "url" -> Json.toJson(getArticleUrl)
        :: "title" -> Json.toJson(getTitle)
        :: "preview" -> Json.toJson("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut euismod pellentesque facilisis. Morbi odio sem, dapibus eget cursus vel, sodales in diam. Nunc porttitor mauris vitae diam imperdiet nec bibendum magna eleifend. Mauris sapien lectus, sodales et tincidunt at, aliquam a leo. Nullam quis enim vitae ligula condimentum tempus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam ut facilisis quam. Aenean sed dapibus sapien. Nulla facilisi.")
        :: "image" -> Json.toJson(getImageUrl)
        :: "topics" -> JsArray(Seq(Json.toJson("Tiger Dog"), Json.toJson("Lemon Party")))
        :: "from_user" -> JsArray(
        JsObject(
          "username" -> Json.toJson("fudgeface")
            :: "full_name" -> Json.toJson("Mr. Fudge Face")
            :: "id" -> Json.toJson("#3:27")
            :: "profile_picture" -> Json.toJson("url here")
            :: Nil
        ) :: Nil)
        :: "shares" -> JsArray(
        JsObject(
          "count" -> Json.toJson("100")
            :: Nil
        ) :: Nil)
        :: Nil).asInstanceOf

    println(ret.toString, "here")
    ret

  }
}

如果我尝试访问 toJson,它就会死掉。其他方法有效。

println("\n\n"+getArticleList(defaultPage, defaultPageSize).head.toJson)

error] application - 

! @6dckhec3c - Internal server error, for request [GET /articles] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[ClassCastException: java.lang.Object cannot be cast to play.api.libs.json.JsValue]]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.4]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.4]
    at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor.jar:2.0.2]
    at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.4]
    at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor.jar:2.0.2]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor.jar:2.0.2]
Caused by: java.lang.ClassCastException: java.lang.Object cannot be cast to play.api.libs.json.JsValue
    at $Proxy53.toJson(Unknown Source) ~[na:na]
    at controllers.ArticleController$$anonfun$index$1.apply(ArticleController.scala:111) ~[classes/:2.0.4]
    at controllers.ArticleController$$anonfun$index$1.apply(ArticleController.scala:97) ~[classes/:2.0.4]
    at play.api.mvc.Action$$anon$1.apply(Action.scala:170) ~[play_2.9.1.jar:2.0.4]
    at play.core.ActionInvoker$$anonfun$receive$1$$anonfun$6.apply(Invoker.scala:126) ~[play_2.9.1.jar:2.0.4]
    at play.core.ActionInvoker$$anonfun$receive$1$$anonfun$6.apply(Invoker.scala:126) ~[play_2.9.1.jar:2.0.4]
[debug] application - [securesocial] calling deleteExpiredTokens()

知道为什么吗?这在我看来没问题。

4

1 回答 1

1

已经有一个类似于Jsonable默认框架的特征。这个特征被称为 a Writes。该toJson方法会自动使用它。

它会像这样工作:

import play.api.libs.json.Json.toJson 

object GraphedArticle {

  implicit object graphedArticleWrites extends Writes[GraphedArticle] {
    def writes(g: GraphedArticle) = 
      toJson(Map(
          "articleId" -> toJson(g.getArticleId),
          "graphId" -> toJson(asVertex().getId.toString)
          "created_time" -> toJson(123123123)))
    }
}

这种方法看起来有点不同:

import play.api.libs.json.Json.toJson

def renderListToJson[T](entities: Iterable[T])(implicit writes:Writes[T]): String = {

  val jsonList = Json.toJson(entities.map(Json.toJson).toSeq)
  val result = Json.toJson(Map(
      "meta" -> Json.toJson(Seq()), 
      "data" -> jsonList))

  Json.stringify(result)
}
于 2013-02-20T07:57:00.953 回答