我目前正在模板中使用session()
播放框架:
@if(session().get("email")==null){
<li><a href="@controllers.routes.General.login">Login</a></li>
}else{
<li><a href="@controllers.routes.General.logout">Logout</a></li>
}
此模板用于我的所有视图。其中一些视图由Java控制器控制,一些视图由Scala控制器控制。
当我点击导致Java控制器的链接时,我没有任何问题,登录和注销的链接都得到了正确处理。
当我点击导致Scala控制器的链接时,我得到一个[RuntimeException: There is no HTTP Context available from here.]
根据我在这里读到的有关scala控制器的内容,我了解到他们在呈现页面时没有返回http上下文,但我真的希望能够在我的模板中使用该会话。
我想过在我的视图,模板和控制器中使用参数session()
,但我相信java会话(play.mvc.http.session)和scala会话之间会发生冲突(播放) .api.mvc.session)play时会编译html页面。
我被困了吗?是否有可能强制scala控制器返回http上下文?
答案 0 :(得分:2)
根本原因可能是Java控制器和Scala控制器的处理方式不同。 我首先在Java中使用我的项目,然后尝试添加更多Scala控制器。我也遇到过这个问题(顺便说一下,我正在使用Play 2.3.2)。
我试图通过使用我自己的ActionBuilder在TheadLocal变量中设置我自己的Http.Context来解决这个问题。
import play.api.mvc._
import scala.concurrent.Future
import play.mvc.Http.Context
import play.core.j.JavaHelpers
object ContextAction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
Context.current.set(JavaHelpers.createJavaContext(request))
block(request)
}
}
然后我的Scala控制器操作只使用这个ContextAction:
class TestController extends Controller {
def test = ContextAction { implicit request =>
Ok(views.html.index())
}
}
这样,索引模板可以访问所有request()/ session()/ etc。
答案 1 :(得分:0)
我可能错了,但我认为你的Scala控制器看起来应该是这样的:
def myaction() = Action { implicit request =>
...
}
而不是:
def myaction() = Action {
...
}
即,您必须将请求添加到Action
的范围内。
并将其添加到您的视图中,位于文件的开头:
@(...)(implicit session:Session)
答案 2 :(得分:0)
好的,我找到了解决这个问题的方法。 这不是真正的审美,但它有效,并完全摆脱了这个问题。
我创建了两个不同的主要模板:scalamain.scala.html
和javamain.scala.html
。
由{1}模板由Scala控制器控制的所有视图使用,并使用通常的技巧来使用会话(隐式参数,请参阅更多here)。
scalamain
模板由Java控制器控制的所有视图使用。 (这些视图很容易使用会话。)
这两个模板当然是一次播放后的相同。
我最终在代码中出现了一些冗余,并将所有操作分开,以便视图仅由一种类型的控制器(scala或java)控制。
我希望这会帮助其他人解决同样的问题。我验证了这个答案,因为它解决了问题,但如果你找到一种更优雅的方法来解决问题,请随时回答。