繁体   English   中英

获取Java中的当前Play session()

[英]Get the current Play session() in Java

我有这个课:

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");
    }
}

但是,当我想访问Play会话时,出现以下错误:

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的文档中:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html

该类的主要描述是:

根据查询关键字将getConnection()调用路由到各种目标DataSource之一的抽象DataSource实现。 后者通常(但不一定) 通过某些线程绑定的事务上下文来确定

因此,该类建议一种获取当前上下文信息的方法应使用线程绑定事务上下文。

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

https://www.playframework.com/documentation/2.3.x/ThreadPools#Java-thread-locals

Play中的Java代码使用本地线程来查找上下文信息,例如当前的HTTP请求。 Scala代码不需要使用线程局部变量,因为它可以使用隐式参数来传递上下文。 线程局部变量用于Java中,因此Java代码可以访问上下文信息,而无需在任何地方传递上下文参数。

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

默认对象包装默认用户线程池。 如果要执行自己的线程处理,则应使用HttpExecution类的帮助程序方法自己获取ExecutionContextExecutor对象。

但是,如果您没有在应用程序中使用自定义线程池,那将不是问题。

就是说,您要做的是:

  1. 为要用作路由器的对象定义ThreadLocalContext。

  2. 放在上下文中。 (如果您使用的是Deadbolt之类的授权框架,或者甚至实现了新的请求过滤器,则可以在控制器中,在安全控制器中进行操作。)

  3. 在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();
   }
}

第2步:

//Demostrative code, not tested, not even compiled
public static void myController() {
   RoutingContext.setRoutingKey(Play.Context.request()); 
   return bla;
}

第三步:

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

问候!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM