viernes, 21 de septiembre de 2012

Interceptores en controladores

A menudo es útil para interceptar procesamientos de cualquier petición, sesión o estado de aplicación. Esto puedes lograrlo con la acción de los interceptores. Actualmente hay dos tipos de interceptores: before and after.

NOTA: Si tu interceptor se aplica a más de un controlador, deberías definir mejor un Filtro. Los filtros pueden aplicarse a múltiples controladores o a URIs sin la necesidad de cambiar la lógica de cada controlador.

- Before Interception
Intercepta procesamientos antes de que la acción se ejecute. Si devuelve false, la acción interceptada no será ejecutada. El interceptor podrá ser definido en todas las acciones de un controlador como lo siguiente:
def beforeInterceptor = {
    println "Tracing action ${actionUri}"
}

El código es declarado en el cuerpo del controlador. Será ejecutado antes que todas las acciones y no interferirá en el procesamiento. Un caso común es una simple autenticación:
def beforeInterceptor = [action: this.&auth, except: 'login']

// defined with private scope, so it's not considered an action 
private auth() { 
if (!session.user) { redirect(action: 'login') return false } }
def login() { // display login page }

El código define un método llamado auth. Un método privado es usado para no exponerlo como acción fuera de todo. El beforeInterceptor define un interceptor que es usado para todas las acciones excepto en la acción login y que ejecuta el método auth. El método auth se referencia usando la sintaxis de puntero de un método Groovy.
Dentro del método detecta si hay un usuario en sesión, si no es así redirige a la acción de login y devuelve un false, causando que la acción interceptada no sea procesada.

- After Interception
Usa la propiedad afterInterceptor para definir un interceptor que es ejecutado después de una acción:
def afterInterceptor = { model ->
    println "Tracing action ${actionUri}"
}

El afterInterceptor toma el resultado del model como argumento y por lo tanto puede manipular el modelo o la respuesta.
Un afterInterceptor puede también modificar el objeto ModelAndView de Spring MVC antes de renderizarlo. E este caso, sería:
def afterInterceptor = { model, modelAndView ->
    println "Current view is ${modelAndView.viewName}"
    if (model.someVar) modelAndView.viewName = "/mycontroller/someotherview"
    println "View is now ${modelAndView.viewName}"
}

Esto permite que la vista sea cambiada basándose en el modelo devuelto por la actual acción. Anotar que el modelAndView puede ser null si la acción que ha sido interceptada llama a un redirect o un render.

No hay comentarios:

Publicar un comentario