我正在使用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]
任何有关如何解决此错误的帮助都将受到高度赞赏!
答案 0 :(得分:0)
看起来你使用tempCall作为一些复杂/慢速逻辑的缓存。 现在你有了一个新的要求,迫使这个逻辑依赖于wID。
因此,tempCall不能只是一个元素的简单val。 您无法访问控制器方法之外的会话或请求。 您的选项从简单到更复杂的订购
正确的决定很大程度上取决于您的要求。
播放缓存模块将为您提供一种简单而灵活的入门方式,默认情况下依赖于ehCache,如果您需要,可以将其更改为使用redis。
https://www.playframework.com/modules/redis-0.2/home