2012-07-13 9 views
17

Soy consciente de Setting HTTP headers in Play 2.0 (scala)? que puede establecer los encabezados de respuesta caso por caso haciendo, por ejemplo, Ok("hello").withHeaders(PRAGMA -> "no-cache").Reproducir 2 - Establecer encabezado en todas las respuestas?

¿Qué sucede si desea establecer ese encabezado, o algunos encabezados diferentes, en las respuestas de todas sus acciones? No querrá repetir el withHeaders en todas partes. Y puesto que este es más como una configuración de toda la aplicación, no puede ser que desee escritores de acción tengan que utilizar una sintaxis diferente para obtener los encabezados (por ejemplo OkWithHeaders(...))

Lo que tenemos ahora es una clase de controlador de base que se parece a

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

pero eso no se siente del todo bien. Parece que debería haber más de una forma al estilo de AOP de definir los encabezados predeterminados y tenerlos agregados a cada respuesta.

+1

Tenga en cuenta que PRAGMA -> no-cache probablemente no va a funcionar de la manera que desea. Vea este enlace: http://www.mnot.net/cache_docs/ Probablemente quiera usar CACHE_CONTROL en lugar de PRAGMA – andrewf

+0

'CACHE_CONTROL ->" max-age = 0 "' debería hacerlo. – andrewf

Respuesta

8

En su Global.scala, envuelva cada llamada en una acción:

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

} 

En este caso, lo único que llamo la acción en el modo dev, lo que hace más sentido para una instrucción de no-cache.

+0

¡Encantador, gracias! Me encontré con una solución similar, pero estaba teniendo problemas para hacer coincidir el tipo parametrizado SimpleResult sin las advertencias del compilador sobre el borrado. Además, tenga en cuenta mi comentario anterior acerca de que PRAGMA es lo incorrecto para usar en el almacenamiento en caché. – andrewf

+0

¡Esto parece una buena respuesta para mí! – gimix

+0

@MariusSoutier - probé la solución que sugeriste, pero en el tiempo de ejecución, siempre obtengo _ "otro" _ y no una "Acción" que pueda usar para agregar encabezados. el tipo de _ "otro" _ en tiempo de ejecución es: 'play.core.Router $ Routes $$ anon $ 4' ¿Alguna idea sobre cómo puedo manejarlo? –

0

Hay muchas maneras. Puede usar action-composition. Luego debe declarar en cada Controlador que desea establecer aquí el encabezado. Otra opción es usar el GlobalSettings. También hay soluciones similares para Java.

+0

No veo dónde puede hacer esto en GlobalSettings, ¿puede ser más específico? Me parece que solo tienes ganchos en la solicitud, no la respuesta. –

+0

Bueno, puedes envolver la Acción normal con la tuya. Entonces creo que tienes acceso al objeto-resultado y allí puedes hacerlo. Solo una idea, porque estoy trabajando con Java. Ahí tienes el contexto que contiene la respuesta. – niels

2

La manera más fácil de lograr un control detallado es mediante el uso de acciones envueltas. En su caso puede ser algo así:

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

y usarlo en la forma:

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

El tema es bastante antiguo, pero con Play 2.1 es aún más simple ahora. Su clase Global.scala debería tener este aspecto:

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" 
    )) 
    } 
} 
Cuestiones relacionadas