我正在尝试在 Play 框架中的 scalaquery 中实现“基于请求”的会话。我使用 scalaquery 创建一个会话,并尝试将其存储在当前的 http 上下文中,如下所示:
def withTransaction[A](bp: BodyParser[A])(f: Request[A] => Result): Action[A] = {
Action(bp) {
request =>
val context = Http.Context.current()
val session = createSession()
session.conn.setAutoCommit(false)
context.args.put("scalaquery.session", session)
try {
val result = f(request)
session.conn.commit()
result
}
catch {
case t: Throwable =>
session.conn.rollback()
throw t
}
finally {
session.close()
context.args.remove("scalaquery.session")
}
}
}
然后我将我的动作包装在我的控制器中,例如:
withTransaction(parse.anyContent) {
Action {
//code that produces a result here
}
}
但是,它在以下行中崩溃:
val context = Http.Context.current()
[RuntimeException: There is no HTTP Context available from here.]
那么,为什么上下文不可用呢?该代码由框架直接调用,因此不应该在该代码执行时设置上下文吗?或者我使用了错误的方式来访问上下文?
编辑:“会话”的类型为 org.scalaquery.session.Session。我想在 HttpContext 中设置它的原因是,以便包装的操作可以以“http范围”的方式访问它,即每个请求单独存储其会话,但所有需要会话的服务都可以在公共中找到它每个请求分开的范围。
我认为问题在于您正在将 Java API 与 Scala 控制器一起使用。Http.Context
仅当您使用 Java 控制器时才设置。您是否考虑过使用Scala 会话 API http://www.playframework.org/documentation/2.0.2/ScalaSessionFlash?
另外,还有一个问题是,为什么需要将session存储在context中呢?我看你最后还是把它删除了。如果您需要的是子操作能够访问会话,您可以将其传递到函数中。
我只是假设session
属于类型Session
def withTransaction[A](bp: BodyParser[A])(f: Session => Request[A] => Result): Action[A] = {
Action(bp) {
request =>
val session = createSession()
session.conn.setAutoCommit(false)
try {
val result = f(session)(request)
session.conn.commit()
result
}
catch {
case t: Throwable =>
session.conn.rollback()
throw t
}
finally {
session.close()
}
}
}
你的子动作是
withTransaction(parse.anyContent) { session => request =>
//code that produces a result here
}
你不需要把它包起来Action
不再因为它已经被包裹了withTransaction
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)