2013-10-10 6 views
13

Ho uno scenario semplice: aggiungere automaticamente un'intestazione di risposta a ogni risposta HTTP; e voglio farlo in Java.Scrittura di filtri personalizzati per Play! 2.2 in Java

Guardando a src/play-filters-helpers/src/main/java/play/filters/*, ci sono esempi di Actions che possono essere applicati come annotazioni. Vorrei evitare di aggiungere @AddMyHeader ad ogni gestore.

Guardando allo Scala Filters in e GzipFilter in particolare, vedo un meccanismo chiaro, ma non sono abbastanza familiare con Scala da estrapolare a Java.

Quindi: dove vado da qui?

risposta

25

Sfortunatamente non esiste ancora un buon modo per creare e utilizzare i filtri da Java. Ma puoi fare quello che ti serve abbastanza facilmente con Scala.

Creare un nuovo file contenente 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")) 
    } 
} 

e creare un nuovo file contenente app/Global.scala:

import filters.AddResponseHeader 
import play.api.mvc.WithFilters 

object Global extends WithFilters(AddResponseHeader) 

che si dovrebbe applicare un nuovo header risposta ad ogni risposta.

UPDATE: C'è un modo per utilizzare questo in un file Global.java:

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

e cambiarne anche l'object AddResponseHeader sopra per class AddResponseHeader.

+0

Questo ha funzionato perfettamente, anche se ho avuto rimuovere il mio Global.java, che ha finito per apparire come: 'object Global estende WithFilters (AddResponseHeader, new GzipFilter())' –

+1

C'è qualche possibilità che può essere aggiunto a 'Global.java'? –

+1

Inserito un modo per farlo nella risposta. –

4

Per aggiungere un filtro personalizzato (MyFilter.class) creare un file Global.java nel pacchetto radice. Testato in play framework 2.3.x e 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

Non C'è una bella Java API disponibili per la creazione di Giocare con i filtri. Tuttavia, è possibile adattare le API Scala esistenti in un buon modello Java.

Ad esempio: realizzazione

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

Esempio:

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

Per un'ulteriore spiegazione di come funziona, vedere il mio blog post su di esso here

Problemi correlati