[英]Using scala and java in play framework 2.1 : Session usage
I'm currently using the session()
of play framework in my template : 我目前正在我的模板中使用play框架的
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>
}
This template is used in all of my views. 此模板用于我的所有视图。 Some of these views are controlled by a Java controller, and some are with a Scala controller.
其中一些视图由Java控制器控制,一些视图由Scala控制器控制。
When I click on links that lead to Java controllers, I have no problems, the links for login and logout are correctly handled. 当我点击导致Java控制器的链接时,我没有问题,正确处理登录和注销的链接。
When I click on links that lead to Scala controllers, I get a [ RuntimeException: There is no HTTP Context available from here.]
当我点击导致Scala控制器的链接时,我得到一个[
RuntimeException: There is no HTTP Context available from here.]
From what I read in here about scala controllers, I understood that they didn't return the http context when rendering a page, but I really want to be able to use the session in my template. 从我在这里读到的关于scala控制器的内容来看,我理解他们在渲染页面时没有返回http上下文,但我真的希望能够在我的模板中使用会话。
I thought about using an argument session()
in my view, templates and controllers, but I believe that there will be a conflict between the java session (play.mvc.http.session) and the scala session (play.api.mvc.session) when play will compile the html pages. 我想在我的视图,模板和控制器中使用参数
session()
,但我相信java会话(play.mvc.http.session)和scala会话(play.api.mvc)之间会发生冲突。 session)play时会编译html页面。
Am I stuck? 我被困了? Is there a possibility to force scala controllers to give back the http context ?
是否有可能强制scala控制器回放http上下文?
The root cause maybe the Java controllers and Scala controllers are handled differently. 根本原因可能是Java控制器和Scala控制器的处理方式不同。 I have my project in Java first, and then try to add more Scala controllers.
我首先在Java中使用我的项目,然后尝试添加更多Scala控制器。 I also came across this problem (BTW, I am using Play 2.3.2).
我也遇到过这个问题(BTW,我正在使用Play 2.3.2)。
I tried to fix this by setting my own Http.Context in the TheadLocal variable using my own ActionBuilder. 我试图通过使用我自己的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)
}
}
Then my Scala controller actions simply use this ContextAction instead: 然后我的Scala控制器操作只是使用这个ContextAction代替:
class TestController extends Controller {
def test = ContextAction { implicit request =>
Ok(views.html.index())
}
}
And this way the index template can access all request() / session() / etc. 这样索引模板就可以访问所有request()/ session()/等。
I may be wrong, but I think that your Scala controllers should look like: 我可能错了,但我认为您的Scala控制器应该如下所示:
def myaction() = Action { implicit request =>
...
}
instead of: 代替:
def myaction() = Action {
...
}
Ie, you have to add the request to the scope of your Action
. 即,您必须将请求添加到您的
Action
范围。
And add it also to your view, at the beginning of the file: 并将其添加到您的视图,在文件的开头:
@(...)(implicit session:Session)
Okay I found a workaround this problem. 好的,我找到了解决这个问题的方法。 This is not really aesthetic, but it works, and gets rid of the problem entirely.
这不是真正的美学,但它有效,并完全摆脱了问题。
I created two different main templates : scalamain.scala.html
and javamain.scala.html
. 我创建了两个不同的主模板:
scalamain.scala.html
和javamain.scala.html
。
The scalamain
template is used by all views that are controlled by a Scala controller, and used the usual trick to use the session (implicit arguments, see more here ). scalamain
模板由Scala控制器控制的所有视图使用,并使用通常的技巧来使用会话(隐式参数,请参见此处 )。
The javamain
template is used by all view that are controlled by a Java controller. javamain
模板由Java控制器控制的所有视图使用。 (these view use the session easily). (这些视图很容易使用会话)。
The two templates are of course, the same once rendered by play. 当然,这两个模板一旦通过播放呈现就相同。
I end up with some redundancy in my code and it took to separate all the actions so that view are controlled by only one type of controller(scala or java). 我最终在代码中出现了一些冗余,并将所有操作分开,以便视图仅由一种类型的控制器(scala或java)控制。
I hope this will help others with the same problem. 我希望这会帮助其他人解决同样的问题。 I validate this answer, as it solves the problem, but feel free to answer if you find a more gracious way to solve it.
我验证了这个答案,因为它解决了问题,但如果你找到一种更优雅的方法来解决它,请随时回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.