Я новичок scala и пытаюсь понять его базовые понятия. С помощью play/scala/slick я пытаюсь реализовать тривиальное приложение, которое позволяет пользователю выполнять операции CRUD для других пользователей. Поэтому проблема, с которой я сталкиваюсь, заключается в том, что я не понимаю, как использовать неявные преобразования для преобразования объекта модели в объект DTO.
Вот что у меня до сих пор:Scala convert model object to DTO
Application.scala
(класс Controller):
//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) Нет сериализатора Json для типа Application.this.userDAO.Entity. Попробуйте реализовать неявные Writes или Format для этого типа. .map {list => Ok (list.map (elem => Json.toJson (elem)))}. Как и где следует преобразовывать пользователя из User в UserDto, чтобы он работал, а не, скажем, уродливым?
Например, в Java я бы реализовал каждый объект Dto с public User to()
и public static UserDto from(User user)
, чтобы я мог их преобразовать. Должен ли я делать то же самое в scala или есть более элегантный способ выполнить эту задачу?
EDITION Отредактированный вариант 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
объекта.
'USERLIST .map {списка => Ok (userList.map (список => list.map (эль => Json.toJson (эль))))}' Почему вы карта над 'userList' но не используйте какие-либо элементы в нем, а вместо этого переместите его снова для каждого элемента? Также 'list.map (elem => Json.toJson (elem))' можно записать как 'list.map (Json.toJson)'. Пожалуйста, укажите точное сообщение об ошибке, которое вы получаете, при вызове 'toJson'. – sirius
@sirius, я добавил сообщение об ошибке, которое я получаю при компиляции. Пожалуйста, см. Обновленный ответ. –