【问题标题】:Writing custom filters for Play! 2.2 in Java为 Play 编写自定义过滤器! 2.2 在 Java 中
【发布时间】:2013-10-18 22:14:03
【问题描述】:

我有一个简单的场景:自动为每个 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。

那么:我从这里去哪里?

【问题讨论】:

    标签: java playframework


    【解决方案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 AddResponseHeader 更改为class AddResponseHeader

    【讨论】:

    • 这工作得很好,虽然我不得不删除我的 Global.java,它最终看起来像:object Global extends WithFilters(AddResponseHeader, new GzipFilter())
    • 有没有可能添加到Global.java
    • 在答案中发布了一种方法。
    【解决方案2】:

    没有很好的 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;
      }
    }
    

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

    【讨论】:

      【解决方案3】:

      要添加自定义过滤器(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};
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-09
        • 1970-01-01
        • 2011-01-31
        • 2016-11-15
        • 1970-01-01
        • 2019-01-03
        • 2016-10-14
        • 1970-01-01
        相关资源
        最近更新 更多