json - Scala Play JSON 映射不适用于继承

标签 json scala playframework-2.0

我有 Java 背景,其中映射 POJO 非常非常简单。我希望 scala/play 也是如此(对于案例类也是如此),但是当我尝试添加一些层次结构时,事情似乎真的弄脏了工作表。

所以,我的具体问题是我正在尝试通过 websocket 发送各种消息,而 JSON 对此非常有用。但是,我不想在每个类中为每种类型的消息重复公共(public)属性,因此继承。

所以,我正在尝试这样的事情:

class WSMessage(messageType:String)
class EventMessage(eventType:String) extends WSMessage("event")
class AlertMessage(alertType:String) extends WSMessage("alert")

可能还有更具体的......

class LoginEventMessage(login:Login) extends EventMessage("login")
class OrderEventMessage(order:Order) extends EventMessage("order")
class TerrainAlertMessage(terrain:Terrain) extends AlertMessage("terrain")

现在,假设我输入了如下内容:

object LoginEventMessage { implicit val fmt = Json.format[LoginEventMessage] }

object Login { implicit val fmt = Json.format[Login] }

在层次结构的每一步的每个对象上(这真的很烦人)我仍然只将最低级别的属性转换为 JSON。

例如

Json.toJson(new LoginEventMessage(theLogin))

产生类似的东西

{ "login": { "username": "foo", "timestamp": "0000000" } }

而不是

{ "messageType": "event", "eventType": "login", "login": { "username": "foo", "timestamp": "0000000" } }

欢迎提供有关如何在不重复最低级别的所有属性的情况下完成此操作的任何指导!

干杯。

编辑添加尝试 #2 我尝试根据 Zoltán 的评论稍微修改一下。这是结果:

object Login { implicit val fmt = Json.format[Login] }
case class Login(username:String, timestamp:DateTime)

object WSMessage { implicit val fmt = Json.format[WSMessage] }
class WSMessage(val messageType:String)
object EventMessage { implicit val fmt = Json.format[EventMessage] }
class EventMessage(val eventType:String) extends WSMessage("event")
object LoginEventMessage { implicit val fmt = Json.format[LoginEventMessage] }
class LoginEventMessage(val login:Login) extends EventMessage("login")

我们会遇到编译错误,因为它们不是案例类(它们不喜欢继承)。

[error] /app/model/dto/WSMessage.scala:15: No unapply or unapplySeq function found
[error] object WSMessage { implicit val fmt = Json.format[WSMessage] }
[error]                                                  ^
[error] /app/model/dto/WSMessage.scala:17: No unapply or unapplySeq function found
[error] object EventMessage { implicit val fmt = Json.format[EventMessage] }
[error]                                                     ^
[error] /app/model/dto/WSMessage.scala:19: No unapply or unapplySeq function found
[error] object LoginEventMessage { implicit val fmt = Json.format[LoginEventMessage] }
[error]                                                          ^
[error] three errors found
[error] (compile:compileIncremental) Compilation failed
[error] application - 

最佳答案

请记住,在声明类时,与案例类相反,构造函数的所有参数都是protected 字段,除非用val 声明。

因此,为了将所有字段公开给 JSON 格式化程序,您需要使用 val 声明它们:

class WSMessage(val messageType:String)
class EventMessage(val eventType:String) extends WSMessage("event")
class AlertMessage(val alertType:String) extends WSMessage("alert")

class LoginEventMessage(val login:Login) extends EventMessage("login")
class OrderEventMessage(val order:Order) extends EventMessage("order")
class TerrainAlertMessage(val terrain:Terrain) extends AlertMessage("terrain")

关于json - Scala Play JSON 映射不适用于继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40735351/

相关文章:

testing - Scala 的静态测试

java - 在 ElasticSearch 中使用 Java API 时如何从 JSON DSL 构造 QueryBuilder?

jquery - 如何从 colorbox iframe 重新获取 fullCalendar(jQuery 插件)?

python - 值错误: Extra Data error when importing json file using python

android - Android 上的 Scala : best strategy for avoiding global data?

scala - 测试期权值(value)的更好方法是什么?

playframework - 如何在 Play 中管理与数据库相关的异常! 2.0/Scala 使用 Anorm

playframework - 如何创建Promise <Result> play2.0框架-Java

playframework - 如何在 Play 2.0 表单中添加全局表单错误以指示乐观锁失败

javascript - 无法从 websocket 消息对象获取 json 值