如何在 play framework(scala) 2.4 中获取当前会话或请求对象?
Posted
技术标签:
【中文标题】如何在 play framework(scala) 2.4 中获取当前会话或请求对象?【英文标题】:how to get current session or request object in play framework(scala) 2.4? 【发布时间】:2016-03-04 05:37:21 【问题描述】:我正在使用带有 Scala 的 Play Framework 2.4 开发应用程序。在我的应用程序中,我想根据 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 framework 1.2 中一样,似乎可以创建会话对象: www.***.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 和 request 对象,但不知何故,不太清楚,如何在 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 日
不知何故,我对使用缓存不是很有信心,因为我不确定在多用户环境中它会如何工作?
现在,我想出了一种可行的新方法,但唯一的问题是,看起来请求是分开处理的,我不知道如何将请求数据从 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]
对于如何修复此错误的任何帮助将不胜感激!
【问题讨论】:
您是否尝试根据当前请求在 Application 类中初始化一个 val?那是行不通的。或者val tempCall
是否在某个方法范围内?
tempCall 只是一个占位符,不在任何方法范围内。 val tempCall 的目的是刷新菜单,以防万一它们被修改或新添加。但是,现在,我想根据会话变量刷新菜单。
【参考方案1】:
看起来您使用 tempCall 作为一些复杂/缓慢逻辑的缓存。 现在您有一个新要求,强制此逻辑依赖于 wID。
因此,tempCall 不能只是一个元素的简单 val。 您不能在控制器方法之外访问会话或请求。 您的选项从简单到复杂排序
如果 wID 只有几个值,则将其转换为 Map 将其转换为 def tempCall(wID: String) 并使用 ScalaCache 或 Redis正确的决定很大程度上取决于您的要求。 Play 缓存模块将为您提供一种简单而灵活的入门方式,默认情况下依赖 ehCache,如果您需要,可以将其更改为使用 redis。https://www.playframework.com/modules/redis-0.2/home
【讨论】:
感谢您的 cmets! tempCall 的基本目的是调用 trait 中的各种方法来初始化/刷新包含菜单的全局对象。 wID 将只是一个 Long 变量,getMenus 方法将依赖于 wID 变量.. 使用 Scala Cache 或 Redis 是一种选择,但 我非常倾向于使用 context 但不确定,如何使用它?任何有关使用上下文的帮助将不胜感激 对不起,没有上下文这样的东西可以解决您的问题。在 java 中有一个 Context 类,您可以使用 Request 或 RequestBuilder 创建它。 好的!谢谢!我会尝试 Scala Cache 或 Redis。以上是关于如何在 play framework(scala) 2.4 中获取当前会话或请求对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Play Framework 2.0 (Scala) 中插入测试数据?
如何在 play framework(scala) 2.4 中获取当前会话或请求对象?
Play Framework 2.4 在 Scala 模板中使用注入变量
Netbeans + Scala + play-framework:找不到 index.html