获取Java中的当前播放会话()

获取Java中的当前播放会话(),java,spring,playframework-2.3,Java,Spring,Playframework 2.3,我有这门课: package ds; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import play.mvc.Http; public class MyRoutingDataSource extends AbstractRoutingDataSource { @Override protected String determineCurrentLookupKey

我有这门课:

package ds;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import play.mvc.Http;

public class MyRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected String determineCurrentLookupKey() {
        return Http.Context.current().session().get("currentDB");
    }
}
但当我想进入播放会话时,我有以下错误:

Caused by: java.lang.RuntimeException: There is no HTTP Context available from here.
at play.mvc.Http$Context.current(Http.java:34) ~[play_2.10-2.3.10.jar:2.3.10]
at play.mvc.Controller.session(Controller.java:72) ~[play_2.10-2.3.10.jar:2.3.10]
我还尝试了HttpExecution.defaultContext()和他的HttpExecutionContext,但无法将其转换为我所需要的Http.Context


我正在考虑获取请求头,但我确实不知道如何从我的类中处理它,以及如何从请求中确定会话

您无法访问该层中的播放上下文,因为它超出了范围。在AbstractRoutingDatasource的文档中:

课程的主要描述是:

路由getConnection()调用的抽象数据源实现 基于查找键的各种目标数据源之一。后者 通常(但不一定)通过一些 线程绑定事务上下文

所以这个类建议获取当前上下文信息的方法应该是使用线程绑定的事务上下文

现在,PlayFramework线程上下文安全吗?阅读播放文档:

游戏中的Java代码使用一个本地线程来查找上下文 诸如当前HTTP请求之类的信息。Scala代码不需要 使用线程局部变量,因为它可以使用隐式参数来传递 而不是上下文。Java中使用了线程局部变量,因此Java代码可以 无需传递上下文即可访问上下文信息 参数无处不在

因此,如果您使用的是Java实现,那么可以使用ThreadLocals作为组件之间的上下文通道。如果创建自己的线程池,请小心,因为同一文档中有一条警告:

默认对象包装默认用户线程池。如果你想 执行自己的线程,然后应该使用HttpExecution类的 帮助器方法来获取ExecutionContextExecutor对象

但如果你不在应用程序中使用自定义线程池,这不会是一个问题

他说,你要做的是:

  • 为要用作路由器的对象定义ThreadLocalContext

  • 放在上下文中。(如果使用Deadbolt等授权框架,甚至实现新的请求过滤器,则可以在控制器、安全控制器中执行此操作。)

  • 在AbstractRoutingDataSource中读取ThreadLocal上下文

  • 重要!不要忘记清理本地线程,否则可能会出现内存泄漏。

    步骤1:

    public class RequestContext {
    
       private static final ThreadLocal<String> contextHolder = 
                new ThreadLocal<String>();
    
       public static void setRoutingKey(String key) {
          contextHolder.set(key);
       }
    
       public static String getRoutingKey() {
          return (String) contextHolder.get();
       }
    
       public static void clearRoutingKey() {
          contextHolder.remove();
       }
    }
    
    步骤3:

    @Override
    protected Object determineCurrentLookupKey() {
      String datasource = RoutingContext.getRoutingKey();
      RoutingContext.clearRoutingKey();
      return datasource;
    }
    
    问候

    @Override
    protected Object determineCurrentLookupKey() {
      String datasource = RoutingContext.getRoutingKey();
      RoutingContext.clearRoutingKey();
      return datasource;
    }