2012-07-13 16 views
17

Jestem świadomy, że od Setting HTTP headers in Play 2.0 (scala)? można ustawić nagłówki odpowiedzi dla poszczególnych przypadków, wykonując na przykład Ok("hello").withHeaders(PRAGMA -> "no-cache").Zagraj w 2 - Ustaw nagłówek we wszystkich odpowiedziach?

Co należy zrobić, jeśli chcesz ustawić ten nagłówek lub kilka różnych nagłówków w odpowiedziach ze wszystkich działań? Nie chcesz już wszędzie powtarzać numeru withHeaders. A ponieważ jest to bardziej jak konfiguracja obejmująca całą aplikację, możesz nie chcieć, aby piszący Action użyli innej składni, aby uzyskać nagłówki (np. OkWithHeaders(...))

Mam teraz klasę kontrolera bazowego, która wygląda jak

class ContextController extends Controller { 
... 
def Ok(h: Html) = Results.Ok(h).withHeaders(PRAGMA -> "no-cache") 
} 

ale to nie jest całkiem w porządku. Wydaje się, że powinien istnieć sposób stylu AOP definiowania domyślnych nagłówków i dodawania ich do każdej odpowiedzi.

+1

Zauważ, że PRAGMA -> no-cache prawdopodobnie nie będzie działać tak, jak zamierza. Zobacz ten link: http://www.mnot.net/cache_docs/ Prawdopodobnie chcesz użyć CACHE_CONTROL zamiast PRAGMA – andrewf

+0

'CACHE_CONTROL ->" max-age = 0 "' powinno to zrobić. – andrewf

Odpowiedz

8

w twojej Global.scala, owinąć każdą rozmowę w działaniu:

import play.api._ 
import play.api.mvc._ 
import play.api.Play.current 
import play.api.http.HeaderNames._ 

object Global extends GlobalSettings { 

    def NoCache[A](action: Action[A]): Action[A] = Action(action.parser) { request => 
    action(request) match { 
     case s: SimpleResult[_] => s.withHeaders(PRAGMA -> "no-cache") 
     case result => result 
    } 
    } 

    override def onRouteRequest(request: RequestHeader): Option[Handler] = { 
    if (Play.isDev) { 
     super.onRouteRequest(request).map { 
     case action: Action[_] => NoCache(action) 
     case other => other 
     } 
    } else { 
     super.onRouteRequest(request) 
    } 
    } 

} 

W tym przypadku, tylko zadzwoń do działania w trybie dev, co sprawia, że ​​największy sens dla instrukcją no-cache.

+0

Piękny, dziękuję! Natknąłem się na podobne rozwiązanie, ale miałem problemy z dopasowaniem sparametryzowanego typu SimpleResult bez ostrzeżeń kompilatora o usunięciu. Zwróć też uwagę na powyższy komentarz dotyczący tego, że PRAGMA jest niewłaściwa do użycia w buforowaniu. – andrewf

+0

To wygląda na dobrą odpowiedź do mnie! – gimix

+0

@MariusSoutier - próbowałem rozwiązania, które zasugerowałeś, ale w czasie wykonywania zawsze otrzymuję _ "inny" _, a nie "Akcja", której mogę użyć do dodania nagłówków. typ _ "other" _ w czasie wykonywania to: 'play.core.Router $ Routes $$ anon $ 4' jakiś pomysł na jak sobie z tym poradzić? –

0

Istnieje wiele sposobów. Możesz użyć action-composition. Następnie musisz zadeklarować przy każdym sterowniku, że chcesz ustawić tutaj nagłówek. Inną opcją jest użycie GlobalSettings. Istnieją podobne rozwiązania dla java.

+0

Nie widzę, gdzie możesz to zrobić w GlobalSettings, czy możesz być bardziej konkretny? Wydaje mi się, że masz tylko haczyki w żądaniu, a nie odpowiedź. –

+0

Cóż, możesz zawinąć normalną akcję własnymi. Wtedy myślę, że masz dostęp do obiektu wynikowego i tam możesz to zrobić. Tylko pomysł, ponieważ pracuję z Javą. Tam masz kontekst, który zawiera odpowiedź. – niels

2

Najprostszym sposobem uzyskania drobiazgowej kontroli jest używanie zapakowanych czynności. W twoim przypadku może to być coś takiego:

object HeaderWriter { 
    def apply(f: Request[AnyContent] => SimpleResult):Action[AnyContent] = { 
     Action { request => 
      f(request).withHeaders(PRAGMA -> "no-cache") 
     } 
    } 
} 

i używać go w taki sposób:

def doAction = HeaderWriter { request => 
    ... do any stuff your want ... 
    Ok("Thats it!") 
} 
14

Temat jest dość stary teraz, ale z luzem 2.1 jest teraz jeszcze prostsze. Twoja klasa Global.scala powinna wyglądać następująco:

import play.api._ 
import play.api.mvc._ 
import play.api.http.HeaderNames._ 

/** 
* Global application settings. 
*/ 
object Global extends GlobalSettings { 

    /** 
    * Global action composition. 
    */ 
    override def doFilter(action: EssentialAction): EssentialAction = EssentialAction { request => 
    action.apply(request).map(_.withHeaders(
     PRAGMA -> "no-cache" 
    )) 
    } 
} 
Powiązane problemy