为 Play 编写自定义滤镜!2.2 在 Java 中

2022-09-04 06:13:46

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

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

具体来看Scala Filters,我看到了一个清晰的机制,但我对Scala还不够熟悉,无法推断出Java。src/play-filters-helpers/src/main/scala/play/filters/*GzipFilter

那么:我该何去何从?


答案 1

不幸的是,还没有一种从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 AddResponseHeaderclass AddResponseHeader


答案 2

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

有关其工作原理的进一步解释,请参阅我在此处的博客文章


推荐