为Play编写自定义过滤器! 2.2用Java

时间:2013-10-10 23:21:37

标签: java playframework

我有一个简单的场景:自动为每个HTTP响应添加一个响应头;我想用Java做这件事。

查看src/play-filters-helpers/src/main/java/play/filters/*,可以将Actions的示例应用为注释。我想避免向每个处理程序添加@AddMyHeader

特别关注src/play-filters-helpers/src/main/scala/play/filters/*GzipFilter中的Scala Filters,我看到了一个明确的机制,但我对Scala不太熟悉,无法推断Java。

那么:我从哪里开始?

3 个答案:

答案 0 :(得分:25)

不幸的是,还没有一种很好的方法来创建和使用Java的过滤器。但是你可以使用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 <T extends EssentialFilter> Class<T>[] filters() {
    return new Class[] {AddResponseHeader.class};
}

并将上面的object AddResponseHeader更改为class AddResponseHeader

答案 1 :(得分:5)

没有一个很好的Java API可用于创建Play过滤器。但是,您可以将现有的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<Result> apply(Function1<RequestHeader, Future<Result>> nextFilter, RequestHeader requestHeader) {
    return nextFilter
            .apply(requestHeader)
            .map(new AbstractFunction1<Result, Result>() {
                     @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;
  }
}

有关其工作原理的进一步说明,请参阅我的博客文章here

答案 2 :(得分:4)

要添加自定义过滤器(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 <T extends EssentialFilter> Class<T>[] filters() {
        return new Class[]{MyFilter.class};
    }
}