我在过滤器(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();
但......你可以看到它真的很难看。没有其他更好的方式来做到这一点吗?
答案 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[]{};
}
}
}