我正在構建一個Scala Play應用程序,其中的事件和數據是以Json格式持久化的,我試圖爲用戶和他們分配的角色建模。我的想法是模擬作爲案例對象的角色,因爲每個標準角色只需要爲應用程序中的所有用戶定義一次,並且我想對特定用戶已分配的角色類型進行模式匹配。到目前爲止,我有這個;在Scala Play應用程序中避免此java.lang.ClassCastException錯誤的正確apply和unapply方法是什麼?
package models
abstract class User {
def displayName: String
def role: Role
}
case class GuestUser(displayName: String, role: Role) extends User {
}
case class RegisteredUser(displayName: String, role: Role) extends User {
}
trait Role { // have tried abstract class too - but like idea of developing stackable traits for role permissions
}
object Role {
implicit val RoleTypeFormat: Format[Role] = Json.format[Role]
def apply(className: String): Role = Class.forName(className: String).asInstanceOf[Role]
def unapply(role: Role): Option[String] = Option(this.getClass.getName) // have also tried .getSimpleName
}
case object GuestUserRole extends Role {
}
case object RegisteredUserRole extends Role {
}
如果我不定義適用,不應用方法object Role
,只依靠使用Json.format[Role]
隱含的價值,我得到或「否取消應用功能發現」錯誤「沒有發現應用功能」 - 所以我加了他們,試圖擺脫這個錯誤。
我無法在沒有將.asInstanceOf[Role]
添加到Role
應用方法的情況下編譯它。現在編譯,但是當我嘗試設置role: Role
參數使用新RegisteredUser
實例,
val role: Role = RegisteredUserRole
新RegisteredUser
實例被創建,其中的角色屬性,都會序列化JSON作爲;
"role":{"className":"models.Role$」}
但是當我嘗試反序列化,我得到Exception in thread "pool-4868-thread-1" java.lang.ClassCastException: java.lang.Class cannot be cast to models.Role
我的目標是用相同的RegisteredUser
實例(或GuestUser
實例)結束了,這樣我就可以在視圖中進行模式匹配控制器,沿着;
def isAuthorized: Boolean = {
role match {
case RegisteredUserRole => true
case GuestUserRole => false
// etc
}
}
任何幫助和建議,將非常感激。我在Scala和Play方面還不夠熟練和知識淵博,不知道我是否正在建模用戶和角色的正確軌道。
我建議定義自定義JSON格式(即不使用'Json.format'快捷方式),而不是嘗試添加'apply'和'unapply'方法,使糖的工作。但要回答你的實際問題,你不能將'Class'強制轉換爲對象實例,你需要使用反射API來獲得它的靜態成員(它的名字就像'MODULE $'),實際的情況。 – lmm 2014-12-19 11:50:19
感謝您的推薦並回答@lmm - 我將探索兩種方法。 – functup 2014-12-19 14:33:45