Writing custom filters for Play! 2.2 in Java

后端 未结 3 816
别那么骄傲
别那么骄傲 2020-12-09 05:06

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

相关标签:
3条回答
  • 2020-12-09 05:40

    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.

    0 讨论(0)
  • 2020-12-09 05:48

    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

    0 讨论(0)
  • 2020-12-09 05:54

    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};
        }
    }
    
    0 讨论(0)
提交回复
热议问题