I have a simple scenario: automatically add a response header to every HTTP response; and I want to do this in Java.
Looking at src/play-filters-helpers/src/ma
Unfortunately there isn't a good way to create and use Filters from Java yet. But you can do what you need pretty easily with Scala.
Create a new file app/filters/AddResponseHeader.scala
containing:
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"))
}
}
And create a new file app/Global.scala
containing:
import filters.AddResponseHeader
import play.api.mvc.WithFilters
object Global extends WithFilters(AddResponseHeader)
That should apply a new response header to every response.
UPDATE: There is a way to use this in a Global.java
file:
@Override
public <T extends EssentialFilter> Class<T>[] filters() {
return new Class[] {AddResponseHeader.class};
}
And also change the object AddResponseHeader
above to class AddResponseHeader
.
There isn't a nice Java API available for creating Play Filters. However, you can adapt the existing Scala APIs into a nice Java template.
For example:
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);
}
Example implementation:
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;
}
}
For a further explanation of how this works, see my blog post about it here
To add a custom filter (MyFilter.class) create a Global.java file in the root package. Tested in PlayFramework 2.3.x and 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};
}
}