如何使用scala中的playframework将json反序列化为密封特征?

RBS*_*RBS 2 json scala playframework

我是scala的新手并且陷入了对象反序列化.我感谢任何帮助.

所以问题是,我有sealed trait Permission一些案例对象扩展它:

sealed trait Permission
case object Administrator extends Permission
case object Dispatcher extends Permission
case object Editor extends Permission
case object NormalUser extends Permission
object Permission {

  def valueOf(value: String): Permission = value match {
    case "Administrator"  => Administrator
    case "Dispatcher"     => Dispatcher
    case "Editor"         => Editor
    case "NormalUser"     => NormalUser
    case _                => throw new IllegalArgumentException()
  }

  def stringValueOf(value: Permission): String = value match {
    case Administrator  => "Administrator"
    case Dispatcher     => "Dispatcher"
    case Editor         => "Editor"
    case NormalUser     => "NormalUser"
    case _              => throw new IllegalArgumentException()
  }

}
Run Code Online (Sandbox Code Playgroud)

我有User案例类Permission:

case class User(id: Option[Int],
                username: String,
                permission: Permission,
                firstName: Option[String]=None,
                lastName: Option[String]=None)
Run Code Online (Sandbox Code Playgroud)

我创建Json.reads[Permission]Json.reads[User],但每当我运行代码,我得到No unapply function found异常.我试图寻找同样的问题,但没有得到任何东西.请帮忙解决这个问题.谢谢.

使用scala 2.11.x和PlayFramework

Kol*_*mar 6

Play只能为案例类自动找出JSON阅读器.在您的情况下,您必须Permission手动定义阅读器:

implicit val permissionReads: Reads[Permission] = 
  __.read[String].map(Permission.valueOf)
Run Code Online (Sandbox Code Playgroud)

如果权限格式出现问题,这将抛出一个实际的异常,而不是返回一个JsError.要解决此问题,您可以使用collect:

implicit val permissionReads: Reads[Permission] = 
  __.read[String].collect(ValidationError("unsupported permission format"))(
    Function.unlift(s => scala.util.Try(Permission.valueOf(s)).toOption))
Run Code Online (Sandbox Code Playgroud)

如果你不想要这个长咒语,Function.unlift(s => scala.util.Try(Permission.valueOf(s)).toOption你可以通过替换valueOf(或添加一个新函数object Permission)来减少它,或者使用一个PartialFunction[String, Permission]或一个返回an Option[Permission]而不是抛出错误的函数.