2013-10-10 41 views
13

我有一个简单的场景:为每个HTTP响应自动添加一个响应头;我想用Java来做到这一点。为Play编写自定义过滤器! 2.2 in Java

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

查看Scala Filters的和GzipFilter具体来说,我看到了一个明确的机制,但我对Scala外推到Java并不熟悉。

所以:我该从哪里出发?

回答

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) 

应适用新的响应报头的每一个反应。

UPDATE:有一个Global.java文件中使用这种方式:

@Override 
public <T extends EssentialFilter> Class<T>[] filters() { 
    return new Class[] {AddResponseHeader.class}; 
} 

,改变上述object AddResponseHeaderclass AddResponseHeader

+0

这完美地工作,但我有删除我的Global.java,它看起来像这样:'对象全局扩展WithFilters(AddResponseHeader,new GzipFilter())' –

+1

有没有任何机会可以添加到'Global.java'? –

+1

发表了一个方法来做到这一点的答案。 –

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}; 
    } 
} 
4

没有一个很好的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