为Play编写自定义filter! 2.2用Java
我有一个简单的场景:自动为每个HTTP响应添加一个响应头; 我想用Java做到这一点。
查看src/play-filters-helpers/src/main/java/play/filters/*
,有一些可以作为注释应用的动作示例。 我想避免将@AddMyHeader
添加到每个处理程序。
特别是在src/play-filters-helpers/src/main/scala/play/filters/*
和GzipFilter
查看Scalafilter ,我看到了一个明确的机制,但是我对Scala不太熟悉,无法推断Java。
那么:我从哪里开始?
不幸的是,还没有一种很好的方法来创建和使用Java的filter。 但是你可以使用Scala轻松地完成你需要的工作。
创建一个新文件app/filters/AddResponseHeader.scala
其中包含:
package filters import play.api.mvc._ import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global object AddResponseHeader extends Filter { def apply(f: (RequestHeader) => Future[SimpleResult])(rh: RequestHeader): Future[SimpleResult] = { val result = f(rh) result.map(_.withHeaders("FOO" -> "bar")) } }
并创建一个新文件app/Global.scala
其中包含:
import filters.AddResponseHeader import play.api.mvc.WithFilters object Global extends WithFilters(AddResponseHeader)
这应该为每个响应应用一个新的响应头。
更新 :有一种方法可以在Global.java
文件中使用它:
@Override public Class [] filters() { return new Class[] {AddResponseHeader.class}; }
并且还将上面的object AddResponseHeader
更改为object AddResponseHeader
class AddResponseHeader
。
没有一个很好的Java API可用于创建Playfilter。 但是,您可以将现有的Scala API调整为一个漂亮的Java模板。
例如:
import play.api.mvc.*; import scala.Function1; import scala.concurrent.Future; import scala.runtime.AbstractFunction1; public abstract class JavaFilter implements Filter { @Override public Future apply(Function1> nextFilter, RequestHeader requestHeader) { return nextFilter .apply(requestHeader) .map(new AbstractFunction1() { @Override public Result apply(Result currentResult) { return Apply(currentResult, requestHeader); } }, play.api.libs.concurrent.Execution.defaultContext()); } @Override public EssentialAction apply(EssentialAction next) { return Filter$class.apply(this, next); } public abstract Result Apply(Result currentResult, RequestHeader requestHeader); }
示例实现:
import play.api.mvc.RequestHeader; import play.api.mvc.Result; public class HelloFilter extends JavaFilter { @Override public Result Apply(Result currentResult, RequestHeader requestHeader) { if (requestHeader.headers().get("X-Filter").isDefined()) { ResultAdapter resultAdapter = new ResultAdapter(currentResult); return resultAdapter.WithHeader("X-Hello", "World!"); } return currentResult; } }
有关其工作原理的进一步说明,请参阅我的博客文章
要添加自定义筛选器(MyFilter.class),请在根包中创建Global.java文件。 在PlayFramework 2.3.x和Java(JDK8)中测试
import play.GlobalSettings; import play.api.mvc.EssentialFilter; public class Global extends GlobalSettings { @Override public Class [] filters() { return new Class[]{MyFilter.class}; } }