13

我有一个简单的场景:自动为每个 HTTP 响应添加响应头;我想在Java中做到这一点。

查看src/play-filters-helpers/src/main/java/play/filters/*,有一些可以用作注释的动作示例。我想避免添加@AddMyHeader到每个处理程序。

具体来说,查看Scala 过滤器src/play-filters-helpers/src/main/scala/play/filters/*GzipFilter看到了一个清晰的机制,但我对 Scala 不够熟悉,无法外推到 Java。

所以:我从这里去哪里?

4

3 回答 3

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.

于 2013-10-11T04:03:14.717 回答
5

没有一个很好的 Java API 可用于创建播放过滤器。但是,您可以将现有的 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;
  }
}

有关其工作原理的进一步说明,请在此处查看我的博客文章

于 2015-04-12T21:35:51.763 回答
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};
    }
}
于 2015-02-12T16:42:22.543 回答