Play!1 …mas o menos completo (3)


Qué es lo siguiente?
Repasamos conceptos básicos como:
-Request
-Render
-Redirect
-Anotaciondes en el controlador
-Sesión de Usuario

Response

HTTP está basado en un modelo request/response (solicitud/respuesta).
Las respuestas pueden estar vacías pero debe hacerse por alguna vía para confirmar que la consulta llegó. En play, una respuesta se envía (por Render) en métodos o redireccionando a una URL específica.

Render

Play tiene un numero de métodos de renderizado que pueden usarse para enviar devuelta las respuestas a el cliente. Estos son:
– renderText()
Para retornar respondiendo con un texto plano.
– renderXML
– renderBinary()
Puede tomar un archivo o un InputStream como un parámetro para devolver contenidos por la llamada de la aplicación. También puede especificar los nombres de archivos con el InputStream para especificar los valores que se mostrarán en la ventana cuando descargue.
-renderJSON()
Podemos usarlo desde un string JSON, un string pre-preparado o un objeto java. Si se usa un objeto, deberá primero serializarse a JSON y luego devuelto.Sin embargo, el método comúnmente más usado es
-render()

El método render renderiza un template Groovy, el cual básicamente permite contruir un HTML a full (y XML, JSON, etc) páginas usando templates para reducir la cantidad de código duplicado. Cuando escriba sobre las Vistas se va a ver esto con detalle.
Más adelante se va a explicar como funciona, ahora solo veamos como trabaja.

package controllers;
 import play.mvc.*;
 public class Application extends Controller {
 public static void index() {
 render();
 }
 public static void sayHello(String myName) {
 render(myName);
 }
 }

El método render es lo suficientemente inteligente como para saber cual acción llamamos. Como en el ejemplo, cuando es llamado desde el metodo index sabe que tiene que renderizar el index.html en la carpeta Application (porque Appliocation es el nombre del controlador).
El segundo método sayHello renderizará el sayhello.html en la misma localización. Siempre y cuando, en este método también le incluyamos datos adicionales. Debemos parsear los argumentos myName en la página sayhello.html. El método renderizado puede tener cualquier número de argumentos, pero solamente renderizar variables locales.
Si no queremos pasar datos a la vista por esta vía, o necesitamos pasar argumentos que no son variables locales, hay otra opción. Directamente accedemos a la variable renderArg Map para agregar argumentos usando el método put.

renderArgs.put(“clave”, elValor);

Si no queremos que renderize el template especificado por nombre del método de la acción, podemos sobreescribir el template en una de dos maneras. Primeramente podemmos llamar al método renderTemplate(), que toma el nombre del template como primer parámetro y los parámetros restantes son los argumentos pasados en el template. Como alternativa, simplemente podríamos llamar a render() y  setear el template como el primer parámetro.

public static void sayHello(String myName){
 render(“Application/dontSayHello.html”, myName);
 //o también aquí podríamos hacer
 //renderTemplate(“Application/dontSayHello.html”, myName);
 }

NOTA: algo importante para tomar conciencia de que todos los métodos render es que una vez que llamamos al método render, además que corre el código de la acción. El render inicia que el evento que devuelve a la aplicación (el navegador) y además no ejecuta ningún otro.

public static void sayHello(String myName){
 render(myName);
 //cuidado: este codigo jamás será ejecutado
 Logger.log(“Hola render!”);
 }

Redirect

Un elemento común de HTTP es la podibilidad de redireccionar, por ejemplo redireccionar un request a Twitter.

Por ejemplo si queremos hacer un servicio acortador de URL (URL shortening service), podríamos tener algo parecido a

public static void performRedirect(String shortURL){
 URLPair url = URLPair.find(“byShortURL”, shortURL).first();
 redirect(url.longURL);
 }

Hay algunos lugares donde Play puede redireccionar automáticamente. Imagina que tu aplicacion tiene dos nuevas funciones.
– crear un nuevo artículo
– mostrar el nuevo artículo
Luego que el artículo se crea podrías querer mostrar el artículo inmediatamente. Puedes hacer algo como lo siguiente.

public static void show(Long id) {
 //Cargar el artículo desde la base de datos
 Articulo articulo = Articulo.findById(id);
 render(articulo);
}
 public static void create(Articulo articulo) {
 //primero guardar el articulo a la base de datos
 articulo.save();
 //ahora mostrar el articulo
 show(articulo.id);
 }

Cuando corra la acción, pasará lo siguiente:
– Play hace que el método show sea llamado, el cual en sí mismo es una action, e intercepta el request (consulta), previniendo que esto sea ejecutado inmediatamente.
– Play calcula qué URL necesita ejecutar la acción show() con el id específico.
– A HTTP 302responde lo enviado a le browser con el header Location:/article?id=12. (Asumiendo que el route para método show del articulo es /articulo y el id generado por el guardar en este evento es el 12).
– El navegador recibirá el 302 redirect, y la solicitud GET /articulo?id=12
– El método mostrar es ejecutado normalmente.

Anotaciones de Controlador (Controller Annotations)

Los Controladores de play vienen con un número de anotaciones que permiten que un evento de una acción de un controlador pueda ser tomado, similar al concepto de Filtros en Servlet. Estos son:
– @Before
– @After
– @Finally

Un interceptor necesita ser static, pero no public.

@Before

Si un interceptor está hecho con esta anotación, indica al framework que antes que cualquier acción se ejecute en este controlador, el interceptor debería ser invocado. Esto puede ser útil por algunas cosas, como la carga de algunos ítems de configuración, o para autenticar a los usuarios que acceden a las acciones en el controlador.

Ejemplo de una autneticación

@Before(unless={“login”,”notauthorised”})
 static void checkAdmin(){
 String usr = session.get(“user”);
 if (usr == null){
 login();
 }
 }
 else {
 User user = User.find(“byUsername”, usr).first();
 if (!user.isAdmin) {
 notauthorised();
 }
 }

Lo anterior chequea si el usuario está logueado chequeando la sesión del objeto, y sino los carga desde la base de datos chequeando si están autorizados.

La anotación @Before puede ser usada por su propia cuenta, sin ningún tipo de soporte pero en este ejemplo te darás cuenta que tiene un parámetro menos. Este parámetro (que puede ser usado con @After y también @Finally) permite excepciones para interceptar. Esto es práctico porque si no especificamos las excepciones (exceptions), podríamos estar en un loop infinito si falla el chequeo Admin, porque no podríamos redireccionar a la página de login, y esto podría llamar a checkAdmin. Sin embargo, nuestro ejemplo no intenta chequear si el usuario es admin si el login o nonauthorised actions fueron llamadas.

@After

La anotación @After trabaja de forma muy similar a @Before, excepto que esto se ejecuta luego que se llama cualquier acción, pero antes que la vista sea renderizada. Esto podría usarse para cargar cualquier item que sea necesario antes de que la vista sea creada.

@Finally

La anotación @Finally es ejecutada una vez que la acción fue completada, y la vista ha sido renderizada y la respuesta es enviada devueta al browser. Esto puede ser usado para poner en orden sabiendo que no tendrá efecto con lo que habrá renderizado para la respuesta.

Considera el siguiente ejemplo de anotaciones que extiende de el controlador Hello World.

public class Application extends Constroller {

 @Before
 static void log0() {Logger.info(“before: “+ response.out.size());}
 @After
 static void log1() {Logger.info(“after: “+ responses.out.size());}
 @Finally
 static void log2() {Logger.info(“finally: “+ response.out.size());}

public static void index() {
 Logger.info(“in index action”);
 render();
 }

public static void sayHello(String myName) {
 render(myName);
 }

}

Serás avisado porque agregamos 3 interceptores y un mensaje info para la acción index antes del método render(). SI ahora en el browser mostramos la página index y vemos el log (en consola) veremos que:
– La anotación before aparece primero y responde que el tamaño es 0;
– El mensaje que agregamos en la acción index se muestra luego;
– La anotación after se muestra tercero, luego de index, con la resuesta deltamaño 0, como el response aún no ha sido generado.
– Finalmente esto se muestra a lo último con el reponse size en 706 (bytes) como la salida fue renderizada y enviada al browser.

La Sesión

Una de las grandes diferencias entre Play y la mayoría (no todos) los otros Java web framewoks disponibles, es que este no permite el uso de un objeto sessión del lado del servidor. En la Servlet API, el objeto session es un objeto que está en la memoria del servidor donde puede ser guardado entre peticiones a el servidor, y mantener en memoria durante la session.
Uno de los grandes defectos es que el servidor queda offline (bajo mucha carga, falla del sistema u otra cosa) los datos del usuario se pierden y en la mayoría de los casos muestra un mensaje de error.
Play fomenta el “no guardes nada” en el desarrollo de aplicaciones web. Hay muchas ventajas en esto, pero no menos que hace fácil escalar tu aplicación sin preocuparte de las “sticky sessions” en el balance de carga.
Sin embargo puedes ver que hay un objeto session disponible desde el Controller. Esto permite guardar alguna información del usuario que puede estar en más qeu una simple página, pero esto se guarda del lado del cliente en una Cookie, mas que en la memoria del servidor, permitiendo no arrastrar ninguna arquitectura para mantener.
Ahí hay otro objeto disponilla llamado flash. Este trabaja en lo mismo como el objseto session que guarda en la cookie, excepto esto exista para el valor de la siguiente consulta.
Debe saber que esas Cookies están limitadas a 4Kb y que son devueltas progresivamente coom parte del HTTP request/response, únicamente puede ser texto.

@wfranck

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: