如何在 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

在 Play Framework 2.4 中为 Scala 实现 Akka

在 Play Framework 2.4 中为 Scala 实现 CORS