【问题标题】:Using scala and java in play framework 2.1 : Session usage在 play framework 2.1 中使用 scala 和 java:会话使用
【发布时间】:2013-06-18 06:37:39
【问题描述】:

我目前在我的模板中使用session() of play 框架:

@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会话(play.api)之间会有冲突.mvc.session) 播放时会编译html页面。

我卡住了吗?是否有可能强制 scala 控制器返回 http 上下文?

【问题讨论】:

    标签: java scala playframework playframework-2.1


    【解决方案1】:

    我可能错了,但我认为您的 Scala 控制器应该如下所示:

      def myaction() = Action { implicit request =>
        ...
      }
    

    代替:

      def myaction() = Action {
        ...
      }
    

    即,您必须将请求添加到Action 的范围内。

    并将它也添加到您的视图中,在文件的开头:

    @(...)(implicit session:Session)
    

    【讨论】:

    • 我认为它也可以解决问题,implicit request 实际上让控制器可以在 http 上下文中使用数据。不幸的是,scala 控制器没有使用这些数据来构建 HTML 页面。 (在做 Ok(...) 时,数据没有提供给页面,所以问题仍然存在)我还认为 #withSession 是为了这个,但它似乎只返回 HTTP 标头,之后已经构建了 HTML 页面...
    • 如我所说,我无法使用此解决方案。我同时使用 Scala 和 java 版本的 Session 对象:play.api.mvc.Sessionplay.mvc.Http.Session因为我只能在 scala 或 java 控制器中检索其中一个(java 控制器返回 java 会话,而 scala 控制器返回 scala 会话)当我声明一个时这些在我的模板(implicit session: play.mvc.Http.Session) 中,另一个不起作用。而且我不能简单地将(implicit session:Session) 作为对象 Session 未找到。
    【解决方案2】:

    好的,我找到了解决此问题的方法。 这不是真正的美学,但它有效,并且完全解决了这个问题。

    我创建了两个不同的主模板:scalamain.scala.htmljavamain.scala.html

    scalamain 模板由 Scala 控制器控制的所有视图使用,并使用通常的技巧来使用会话(隐式参数,请参阅更多 here)。

    javamain 模板被 Java 控制器控制的所有视图使用。 (这些视图很容易使用会话)。

    当然,这两个模板在 play 渲染后是一样的。

    我的代码中出现了一些冗余,它需要将所有操作分开,以便视图仅由一种类型的控制器(scala 或 java)控制。

    我希望这能帮助其他有同样问题的人。我验证此答案,因为它解决了问题,但如果您找到更优雅的解决方法,请随时回答。

    【讨论】:

      【解决方案3】:

      根本原因可能是 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.

      【讨论】:

        猜你喜欢
        • 2013-01-04
        • 1970-01-01
        • 2013-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        相关资源
        最近更新 更多