2013-11-20 73 views
2

我的scala技能缺乏,但我一直在摔跤有了这个。但是我有序列化和反序列化JSON的问题。我搜索并搜索了StackOverflow,但不幸的是我无法将它拼凑在一起。找不到类型为List [(java.util.UUID,String,String,String,Int,Int,Int,Int,Int,java.sql.Timestamp)]的Json反序列化程序]

所以这是我的最后一招..

我的模式是:

package models 

import java.util.UUID 
import java.sql.Timestamp 


import play.api.db._ 
import play.api.Play.current 
import play.api.libs.json._ 


import slick.driver.PostgresDriver.simple._ 
import Database.threadLocalSession 

case class User(
    id:UUID, 
    username: String, 
    password: String, 
    email: String, 
    comment_score_down: Int, 
    comment_score_up: Int, 
    post_score_down: Int, 
    post_score_up: Int, 
    created_on: Timestamp) 

object Users extends 
    Table[(UUID, String, String, String, Int, Int, Int, Int, Timestamp)]("users"){ 

    implicit object UserFormat extends Format[User] { 

    implicit object UUIDFormatter extends Format[UUID] { 
     def reads(s: JsString): UUID = java.util.UUID.fromString(s.toString) 
     def writes(uuid: UUID) = JsString(uuid.toString) 
    } 

    implicit object TimestampFormatter extends Format[Timestamp] { 
     def reads(s: JsValue): Timestamp = new Timestamp(s.toString.toLong) 
     def writes(timestamp: Timestamp) = JsString(timestamp.toString) 
    } 


    def reads(json: JsValue): User = User(
     (json \ "id").as[UUID], 
     (json \ "username").as[String], 
     (json \ "password").as[String], 
     (json \ "email").as[String], 
     (json \ "comment_score_down").as[Int], 
     (json \ "comment_score_up").as[Int], 
     (json \ "post_score_down").as[Int], 
     (json \ "post_score_up").as[Int], 
     (json \ "created_on").as[Timestamp] 
    ) 
    def writes(u: User): JsValue = JsObject(List(
     "id" -> JsString(u.id.toString), 
     "username" -> JsString(u.username), 
     "password" -> JsString(u.password), 
     "email" -> JsString(u.email), 
     "comment_score_down" -> JsString(u.comment_score_down.toString), 
     "comment_score_up" -> JsString(u.comment_score_up.toString), 
     "post_score_down" -> JsString(u.post_score_down.toString), 
     "post_score_up" -> JsString(u.post_score_up.toString), 
     "created_on" -> JsString(u.created_on.toString) 
     )) 
    } 


    def id = column[UUID]("ID", O.PrimaryKey) // This is the primary key column 
    def username = column[String]("username") 
    def password = column[String]("password") 
    def email = column[String]("email") 
    def comment_score_down = column[Int]("comment_score_down") 
    def comment_score_up = column[Int]("comment_score_up") 
    def post_score_down = column[Int]("post_score_down") 
    def post_score_up = column[Int]("post_score_up") 
    def created_on = column[Timestamp]("created_on") 

    def * = id ~ username ~ password ~ email ~ comment_score_down ~ 
    comment_score_up ~ post_score_down ~ post_score_up ~ created_on 

} 

我的控制器:

def getUsers = Action { 
    val json = database withSession { 
     val users = for (u <- Users) yield u.* 
     Json.toJson(users.list) 
    } 
    Ok(json).as(JSON) 

    } 

谢谢您的时间!

回答

4

凯,我知道它甜。

提出了一些修改,以我的模型:

case class User(
    id:UUID, 
    username: String, 
    password: String, 
    email: String, 
    comment_score_down: Option[Int], 
    comment_score_up: Option[Int], 
    post_score_down: Option[Int], 
    post_score_up: Option[Int], 
    created_on: Timestamp) 

object Users extends Table[User]("users"){  

我也改变了我的对象签名,以便它可以返回一个类型的用户,而不仅仅是用户的参数。我只需将<>(User,User.unapply _)附加到我的投影方法(*)。

但在我的控制器:

我只需要:

implicit object UserWrites extends Writes[User] { 

    def writes(u: User) = Json.obj(
     "id" -> JsString(u.id.toString), 
     "username" -> JsString(u.username), 
     "password" -> JsString(u.password), 
     "email" -> JsString(u.email), 
     "comment_score_down" -> JsNumber(u.comment_score_down.getOrElse(0).toInt), 
     "comment_score_up" -> JsNumber(u.comment_score_up.getOrElse(0).toInt), 
     "post_score_down" -> JsNumber(u.post_score_down.getOrElse(0).toInt), 
     "post_score_up" -> JsNumber(u.post_score_up.getOrElse(0).toInt), 
     "created_on" -> JsString(u.created_on.toString) 
    ) 


    } 

作为控制器类的成员。

所以现在我的控制器动作就是:

def getUsers = Action { 

    val json = database withSession { 
     val users = for (u <- Users) yield u 
     Json.toJson(users.list) 
    } 
    Ok(json).as(JSON) 
    } 

编辑:

另外,我搬到了getUsers代码到我的模型作为的findAll方法,也动了我写到那里了。我不喜欢数据逻辑控制器是...

所以在我的控制我只有一个方法/措施:

def getUsers = Action { 
    Ok(Users.findAll).as(JSON) 
    } 

我的模型现在看起来像:

package models 

import java.util.UUID 
import java.sql.Timestamp 


import play.api.db._ 
import play.api.Play.current 
import play.api.libs.json._ 


import slick.driver.PostgresDriver.simple._ 
import Database.threadLocalSession 

case class User(
    id:UUID, 
    username: String, 
    password: String, 
    email: String, 
    comment_score_down: Option[Int], 
    comment_score_up: Option[Int], 
    post_score_down: Option[Int], 
    post_score_up: Option[Int], 
    created_on: Timestamp) 

object Users extends Table[User]("users") { 

    lazy val database = Database.forDataSource(DB.getDataSource()) 

    def id = column[UUID]("id", O.PrimaryKey) // This is the primary key column 
    def username = column[String]("username") 
    def password = column[String]("password") 
    def email = column[String]("email") 
    def comment_score_down = column[Option[Int]]("comment_score_down") 
    def comment_score_up = column[Option[Int]]("comment_score_up") 
    def post_score_down = column[Option[Int]]("post_score_down") 
    def post_score_up = column[Option[Int]]("post_score_up") 
    def created_on = column[Timestamp]("created_on") 

    implicit object UserWrites extends Writes[User] { 

    def writes(u: User) = Json.obj(
     "id" -> JsString(u.id.toString), 
     "username" -> JsString(u.username), 
     "password" -> JsString(u.password), 
     "email" -> JsString(u.email), 
     "comment_score_down" -> JsNumber(u.comment_score_down.getOrElse(0).toInt), 
     "comment_score_up" -> JsNumber(u.comment_score_up.getOrElse(0).toInt), 
     "post_score_down" -> JsNumber(u.post_score_down.getOrElse(0).toInt), 
     "post_score_up" -> JsNumber(u.post_score_up.getOrElse(0).toInt), 
     "created_on" -> JsString(u.created_on.toString) 
    ) 
    } 

    def * = id ~ username ~ password ~ email ~ comment_score_down ~ 
    comment_score_up ~ post_score_down ~ post_score_up ~ created_on <> 
    (User, User.unapply _) 

    def findByPK(pk: UUID) = 
    for (entity <- Users if entity.id === pk) yield entity 

    def findAll = database withSession { 
     val users = for (u <- Users) yield u 
     Json.toJson(users.list) 
    } 

} 
-1

看起来您的错误与您的写入方法有关。您已为用户实施了反序列化器,但没有为用户列表实施一个反序列器。我可以提供的最佳建议是创建一个带有List [User]参数类型的写入方法。

+2

如果有一个类型为“T”的反序列化器,那么play也会知道如何反序列化List [T]'。 –

相关问题