Mic*_*ech 1 postgresql scala spray-json slick akka-http
希望你能帮我解决这个问题.使用Akka HTTP,Slick和PosgreSQL,我正在尝试实现一个公告板作为练习.您可以在这里找到它的最新版本以获得完整的图片.
我所拥有的,简而言之:
我有这样的表:
final class Posts(tag: Tag) extends Table[Post](tag, "POSTS") with CustomColumnTypes {
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def threadId = column[Long]("THREAD_ID")
def secretId = column[String]("SECRET")
def pseudonym = column[String]("PSEUDONYM")
def email = column[String]("EMAIL")
def content = column[String]("CONTENT")
def created = column[DateTime]("CREATED")
final class Threads(tag: Tag) extends Table[Thread](tag, "THREADS") {
def threadId = column[Long]("THREAD_ID", O.PrimaryKey, O.AutoInc)
def subject = column[String]("SUBJECT")
Run Code Online (Sandbox Code Playgroud)
和域模型:
case class Post(
postId: Option[Long] = None,
threadId: Option[Long],
secretId: String,
pseudonym: String,
email: String,
content: String,
created: DateTime = DateTime.now)
case class Thread(
threadId: Option[Long] = None,
subject: String
case class NewThreadWithPost(
postId: Option[Long] = None,
subject: String,
secretId: String,
pseudonym: String,
email: String,
content: String)
Run Code Online (Sandbox Code Playgroud)
使用这样写出的自定义协议:
trait TextboardJsonProtocol extends DefaultJsonProtocol with SprayJsonSupport with DateTimeHelper {
implicit object DateTimeFormat extends RootJsonFormat[DateTime] {
def read(value: JsValue) = value match {
case dt: JsValue => value.convertTo[DateTime]
case _ => deserializationError("DateTime expected")
}
def write(c: DateTime) = JsString(c.toString)
}
implicit val threadFormat = jsonFormat2(Thread.apply)
implicit val postFormat = jsonFormat7(Post.apply)
implicit val newThread = jsonFormat6(NewThread.apply)
}
Run Code Online (Sandbox Code Playgroud)
和这样的路线:
def route: Route = {
...
post {
entity(as[Post]) { post =>
complete(createPost(Some(threadId), post).toJson) }
...
post {
entity(as[NewThread]) { thread =>
(master ? CreateNewThread(thread)).mapTo[NewThread]
complete(StatusCodes.Created) }
...
Run Code Online (Sandbox Code Playgroud)
我打算做什么以及失败的地方:
我打算使用这种方法添加新的Thread和new Post,它很有用:
def createNewThread(nt: NewThread) = {
exec(threads += Thread(None, nt.subject))
exec(posts += Post(None, lastId, secretId, nt.pseudonym, nt.email, nt.content, DateTime.now))
}
Run Code Online (Sandbox Code Playgroud)
什么是不起作用的是这个看似相似的方法我用来创建帖子:
def createPost(threadId: Option[Long], p: Post) = {
exec(posts returning posts.map(_.secretId)
+= Post(None, p.threadId, secretId, p.pseudonym, p.email, p.content, DateTime.now))
}
Run Code Online (Sandbox Code Playgroud)
怎么了?
[error] Uncaught error from thread [default-akka.actor.default-dispatcher-7] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[default]
[error] java.lang.StackOverflowError
[error] at main.scala.textboard.TextboardJsonProtocol$DateTimeFromat$.read(Protocol.scala:22)
[info] [ERROR] [SECURITY][12/11/2016 23:03:22.301] [default-akka.actor.default-dispatcher-7] [akka.actor.ActorSystemImpl
(default)] Uncaught error from thread [default-akka.actor.default-dispatcher-7] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled [error] at spray.json.JsValue.convertTo(JsValue.scala:31) <- repeated tens of times
[error] at main.scala.textboard.TextboardJsonProtocol$DateTimeFormat$.read(Protocol.scala:23) <- repeated tens of times
[error] at main.scala.textboard.TextboardJsonProtocol$DateTimeFormat$.read(Protocol.scala:21) <- repeated tens of times
Java.lang.RuntimeException: Nonzero exit code returned from runner: -1 at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code returned from runner: -1
[error] Total time: 18 s, completed 2016-12-11 23:19:16
Run Code Online (Sandbox Code Playgroud)
我已经尝试过了什么
你让自己无限循环DateTimeFormat.你正在打电话给convertTo你read,并convertTo打电话read(参见spray-json来源).
使用类似的东西
implicit object DateJsonFormat extends RootJsonFormat[DateTime] {
private val parser : DateTimeFormatter = ??? // your parser here
override def write(obj: DateTime) = JsString(parser.print(obj))
override def read(json: JsValue) : DateTime = json match {
case JsString(s) => parser.parseDateTime(s)
case _ => throw new Exception("Malformed datetime")
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
859 次 |
| 最近记录: |