0

私はスカラ初心者であり、基本概念を理解しようとしています。私はplay/scala/slickを使用して、ユーザーが別のユーザーに対してCRUD操作を実行できるようにする簡単なアプリケーションを実装しようとしています。だから私が直面する問題は、モデルオブジェクトをDTOオブジェクトに変換するために暗黙的な変換をどのように使用すべきか理解していないということです。モデルオブジェクトをDTOに変換する

Application.scala(Controllerクラス):

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

UserDto.scala(DTO:

//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 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 => Ok(list.map(elem => Json.toJson(elem))})。どのように、私はUserDtoからUserDtoへの変換を実装すればよいのですか?

たとえば、Javaでは、私はpublic User to()public static UserDto from(User user)の各Dtoオブジェクトを実装して変換することができます。私はスカラーで同じことをするべきですか、この仕事を達成するためのよりエレガントな方法がありますか? users方法の

EDITION 編集されたバージョン:

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))) } 

コンパイラがuserWriterUserDto内のオブジェクトを参照していないようです。

+0

'USERLIST の.map {リスト=> OK(userList.map(リスト=> list.map(elemは=> Json.toJson(elemは))))}'なぜあなたはuserList' '上にマッピングんが、その中のどのアイテムも使用せず、代わりにすべてのアイテムについて再びその上にマップします。 'list.map(elem => Json.toJson(elem))'は 'list.map(Json.toJson)'と書くことができます。 'toJson'を呼び出すときに、正確なエラーメッセージを提供してください。 – sirius

+0

@sirius、コンパイル時にエラーメッセージが表示されました。更新された回答をご覧ください。 –

答えて

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の静的メソッドと同等です。そこから、スカラの暗黙の解決メカニズムcan find them

+0

ありがとう、Alvaro!私はこのバグを修正しましたが、残念ながらコンパイルエラーは消えませんでした。 –

+0

暗黙的に動作するには、このパスが必要です。 'User - > UserDTO - > [UserDTO]'を書き込みます。しかし、暗黙はそれのように自動的に連鎖しません。 'User'を' UserDTO'に明示的に変換する必要があります。あるいは、型の値を与えることでコンパイラを少し助ける必要があります。 'Json.toJson(elem:UserDTO)' –

+0

ありがとう、Alvaro。私はこの問題を解決することができましたが、コンパイラは '書き込み'について文句を言うようになりました...私はコードを更新し、ここにエラーがあります: 'Error:(41、24)Seq [play.api.libs。 json.JsValue]をHTTPレスポンスに変換します。 Writeable [Seq [play.api.libs.json.JsValue]] を定義してみてください.map {list => Ok(list.map(elem => Json.toJson(elem:UserDto)))} '。スカラへの移行は本当に厳しいです.. –

関連する問題