在play框架过滤器中向会话添加数据

时间:2016-10-17 12:09:13

标签: java scala playframework-2.0

我在过滤器(EssentialFilter)中向会话添加数据时遇到问题。

在scala api中有方法 <add name="LocalSqlServer" connectionString="Data Source=MCBALOO;Initial Catalog=SmartDeskDb;Persist Security Info=True;User ID=sa;Password=password123$" providerName="System.Data.SqlClient"/> <add name="SmartDeskDbConnectionString" connectionString="Data Source=MCBALOO;Initial Catalog=SmartDeskDb;User ID=sa;Password=password123$" providerName="System.Data.SqlClient"/> Result.withSession,但java api中没有。

如何使用新会话数据从过滤器返回结果?

试图这样做:

Result.withNewSession

从我在debug / sources中看到的,当结果返回到累加器映射块时,结果已经构建了ResponseHeader,并且会话的修改不会改变事物。

我尝试使用@Override public EssentialAction apply(final EssentialAction next) { return EssentialAction.of( request -> { if (isAllowed(request)) { Accumulator<ByteString, Result> accumulator = next.apply(request); return accumulator.map(result -> { Session session = result.session(); session.put("asdf", Long.toString(System.currentTimeMillis())); return result; }, executor); } else { return Accumulator.done(Results.unauthorized()); } }); } 将结果转换为scala并提供新的会话项(asScala())但是我在将java Session转换为scala / play Session时遇到了问题。也许有人可以指出如何正确地做到这一点?

withSession()

[编辑]

我得到了这个:

Session session = result.session();
session.put("asdf", Long.toString(System.currentTimeMillis()));

play.api.mvc.Session newSession = ...?

return result.asScala().withSession(newSession).asJava();

但......你可以看到它真的很难看。没有其他更好的方式来做到这一点吗?

1 个答案:

答案 0 :(得分:0)

我建议您将过滤器完全转换为scala。即使在那里,它也不是无痛的,但是,比你同意的“丑陋”代码更好。

一个例子是:

  import akka.stream.Materializer
  import javax.inject._
  import play.api.Logger
  import play.api.mvc._
  import scala.concurrent.{ExecutionContext, Future}

  @Singleton
  class ExampleFilter @Inject()(
                                   implicit override val mat: Materializer,
                                   exec: ExecutionContext) extends Filter {


    override def apply(nextFilter: RequestHeader => Future[Result])
                      (requestHeader: RequestHeader): Future[Result] = {
      // Run the next filter in the chain. This will call other filters
      // and eventually call the action. Take the result and modify it
      // by adding a new header.

      val start = System.currentTimeMillis()
      nextFilter(requestHeader).map { result =>
        val end = System.currentTimeMillis() - start;
        Logger.debug(s"Service time in milliseconds: ${end}")
        result.withSession(requestHeader.session + ("ServiceTime" -> s"${end}"))
      }
    }

  }

可能你知道这一点,但认为这只是鼓励仅使用scala。

不幸的是Java for play并不适合。您经常会遇到有关转化的问题。真痛苦......

修改

为了在您的java过滤器中包含scala过滤器,您应该在Filters.java中执行以下操作:(从play-java示例中修改)(重要部分:exampleFilter.asJava()

@Singleton
public class Filters implements HttpFilters {

  private final Environment env;
  private final EssentialFilter exampleFilter;

  @Inject
  public Filters(Environment env, ExampleFilter exampleFilter) {
    this.env = env;
    this.exampleFilter = exampleFilter.asJava();
  }

  @Override
  public EssentialFilter[] filters() {
    // Use the example filter if we're running development mode. If
    // we're running in production or test mode then don't use any
    // filters at all.
    if (env.mode().equals(Mode.DEV)) {
      return new EssentialFilter[]{exampleFilter};
    } else {
      return new EssentialFilter[]{};
    }
  }
}