Scala将模型对象转换为DTO

时间:2016-10-13 10:57:22

标签: scala playframework functional-programming implicit-conversion

我是scala新手,并试图了解它的基本概念。使用play / scala / slick我试图实现简单的应用程序,允许用户对其他用户执行CRUD操作。所以我面临的问题是,我不明白应该如何使用隐式转换将模型对象转换为DTO对象。
这是我到目前为止所得到的:

Application.scala(控制器类):

//returns list of users  
def users = Action.async {
    val userList = userDAO.all()
    userList
      .map { list => Ok(list.map(elem => Json.toJson(elem))) }
      .recover { case _ => InternalServerError }
}   

User.scala(模型对象,表示数据库中的条目):

case class User(id: Long, login: String, password: String) extends BaseEntity

UserDto.scala(DTO,对象,代表用户列表中的用户):

case class UserDto(id: Long, login: String) {
  implicit def userWriter = Json.writes[UserDto]

  implicit def user2UserDto(user: User): UserDto = UserDto(user.id, user.login)
}  

在上面的代码中,在#1标记处,我收到一条错误,指出User无法转换为json。确切的错误消息:错误:(40,53)找不到类型为Application.this.userDAO.Entity的Json序列化程序。尝试为此类型实现隐式写入或格式。       .map {list =>好的(list.map(elem => Json.toJson(elem)))} 。我应该如何以及在何处实现从User到UserDto的转换,以便它可以工作而不是丑陋?

例如,在Java中,我将使用public User to()public static UserDto from(User user)实现每个Dto对象,以便我可以转换它们。我是否应该在scala中执行相同的操作,或者有更优雅的方法来完成此任务?

users方法的编辑版本:

def users = Action.async {
  val userList = userDAO.all()
  userList
    .map { list => Ok(list.map(elem => Json.toJson(elem : UserDto))) }
    .recover { case _ => InternalServerError }
}  

出现以下编译错误:

Error:(41, 24) not enough arguments for method apply: (implicit writeable: play.api.http.Writeable[Seq[play.api.libs.json.JsValue]])play.api.mvc.Result in class Status.
Unspecified value parameter writeable.
      .map { list => Ok(list.map(elem => Json.toJson(elem : UserDto))) }  


Error:(41, 24) Cannot write an instance of Seq[play.api.libs.json.JsValue] to HTTP response. Try to define a Writeable[Seq[play.api.libs.json.JsValue]]
      .map { list => Ok(list.map(elem => Json.toJson(elem : UserDto))) }  

编译器似乎没有在userWriter对象中看到UserDto

1 个答案:

答案 0 :(得分:1)

不要在案例类中定义里面的含义。在companion object

中定义它们
case class UserDto(id: Long, login: String)

object UserDto {
  implicit def userWriter = Json.writes[UserDto]

  implicit def user2UserDto(user: User): UserDto = UserDto(user.id, user.login)
}

当您在案例类中定义它们时,它们将成为仅可从类的实例获得的实例方法。在伴随对象上定义它们时,它们是全局定义的(不绑定到实例),它们等同于java中的静态方法。从那里开始,scala的隐式解析机制can find them