如何在Play框架(scala)2.4中获取当前会话或请求对象?

时间:2016-03-04 05:37:22

标签: scala session model-view-controller playframework request

我正在使用Play Framework 2.4和Scala开发一个应用程序。在我的应用程序中,我想根据URL检索菜单。因此,我需要将会话对象(最好)或请求对象传递给特征。

我知道,如何在控制器方法或视图模板中访问会话,但我需要访问控制器方法之外的会话。

我的示例代码如下:

trait SomeTrait{

  var webID: String 

  implicit def getMenus(wID: Long): GlobalData = {
    val menus = someDao.getActiveMenus(wID)
 }
}

class Application  extends Controller with SomeTrait{
    val someForm = Form(
                        mapping(
                          "field1" -> longNumber,
                          "field2" -> nonEmptyText
                        )(SomeClass.apply)(SomeClass.unapply))
   def otherDao = new OtherDAO

   // ================= this will refresh menus ================
   val tempCall = getMenus(request.session.get("wID").getOrElse("-1").toLong) //Here I need to access session variable
   // ========================================================== 

   def someDef = IsAuthenticatedAsync {user => implicit request =>
     val wid = request.session.get("wID").getOrElse("-1").toLong //this works perfectly fine
     Future.successful(Ok(views.html.some.someView(wid, someForm)))
  }
}   

与Play框架1.2一样,似乎可以创建会话对象: www.stackoverflow.com/questions/3654582/object-session-in-playframework https://www.playframework.com/documentation/1.2/api/play/mvc/Scope.Session.html

事实上,您可以在Play Framework JAVA apis中获取Session和请求对象但不知何故,它不是很清楚,如何在Play Framework Scala中执行此操作?

https://www.playframework.com/documentation/2.4.4/api/java/play/mvc/Http.Context.Implicit.html

如果使用Scala在Play Framework 2.4的控制器中无法获取请求或会话对象外的方法,我可以使用Play Cache吗?你在我的代码中看到使用缓存有什么问题吗? (www.playframework.com/documentation/2.4.x/ScalaCache)

事实上,我也在关注Redis Cache(www.redis.io/documentation)

我们将非常感谢您的帮助/建议!

=============================================== ==================

编辑:2016年3月5日

不知何故,我对使用Cache不太自信,因为我不确定在多用户环境中,它将如何运作?

现在,我已经提出了一种新方法,但是只有问题是,看起来,请求是单独处理的,我不知道如何将请求数据从Java控制器传递给Scala控制器?

package controllers;

import play.*;
import play.mvc.*;

import views.html.*;

public class BaseJavaController extends Controller {

    private play.mvc.Http.Request rq = request();
    private String w1ID = session("wsID"); 

    protected String getW1ID() {  // define getter
    return w1ID;
    }

    protected void setW1ID(String wid) {  // define setter
        this.w1ID = wid;
    }  
}

正如您所看到的,我能够在Java控制器中获取请求和会话对象,并且使用guice注入,我能够成功地将Java控制器注入Scala控制器。

但是在运行时,它会出错:

[ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, java.lang.RuntimeException: There is no HTTP    Context available from here.
  at controllers.BaseJavaController.<init>(BaseJavaController.java:8)
  while locating controllers.BaseJavaController
    for parameter 0 at controllers.Application.<init>(Application.scala:138)
  while locating controllers.Application

1 error] 

任何有关如何解决此错误的帮助都将受到高度赞赏!

1 个答案:

答案 0 :(得分:0)

看起来你使用tempCall作为一些复杂/慢速逻辑的缓存。 现在你有了一个新的要求,迫使这个逻辑依赖于wID。

因此,tempCall不能只是一个元素的简单val。 您无法访问控制器方法之外的会话或请求。 您的选项从简单到更复杂的订购

  • 如果wID只有几个值
  • ,则将其转换为地图
  • 将其转换为def tempCall(wID:String)并使用ScalaCache或Redis

正确的决定很大程度上取决于您的要求。 播放缓存模块将为您提供一种简单而灵活的入门方式,默认情况下依赖于ehCache,如果您需要,可以将其更改为使用redis。
https://www.playframework.com/modules/redis-0.2/home