jueves, 8 de diciembre de 2011

Google App Engine: creando JSP


Uso de JSP

Aunque podríamos generar el código HTML para la interfaz de usuario directamente a partir del código Java del servlet, sería algo difícil de mantener ya que el código HTML se complica, recuerden que JSP es una evolucion de Serlvlet. Es más conveniente utilizar un sistema de plantillas en el que la interfaz de usuario esté diseñada e implementada en archivos independientes con los marcadores y la lógica necesarios para insertar los datos proporcionados por la aplicación. Existen muchos sistemas de plantillas disponibles para Java que podrían ser compatibles con App Engine.
Nosotros utilizaremos la tecnología JavaServer Pages (JSP) para implementar la interfaz de usuario del libro de visitas. Las JSP forman parte del estándar de servlet. App Engine compila los archivos JSP en el WAR de la aplicación de forma automática y los asigna a rutas de URL.

¡Hola, JSP!

La aplicación de libro de visitas escribe cadenas en un flujo de salida, aunque esto también podría escribirse como una JSP. Empecemos trasladando la última versión del ejemplo a una JSP.
En el directorio war/, crea un archivo llamado guestbook.jsp con el siguiente contenido:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>

<html>
  <body>

<%
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();
    if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>
<%
    } else {
%>
<p>Hello!
<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>
to include your name with greetings you post.</p>
<%
    }
%>

  </body>
</html>
De forma predeterminada, cualquier archivo en war/ o en un subdirectorio (distinto de WEB-INF/) cuyo nombre termine en .jsp se asigna de forma automática a una ruta de URL. La ruta de URL es la ruta al archivo .jsp, incluido el nombre de archivo. Esta JSP se asigna de forma automática a la URL /guestbook.jsp.
En la aplicación de libro de visitas, queremos que esta sea la página principal de la aplicación y que aparezca cuando un usuario acceda a la URL /. Una forma sencilla de hacer esto es declarar en web.xml que guestbook.jsp es el servlet de "bienvenida" (welcome) de esta ruta.
Modifica war/WEB-INF/web.xml y reemplaza el elemento <welcome-file> actual de <welcome-file-list>. Asegúrate de eliminar index.html de la lista, ya que los archivos estáticos tienen preferencia sobre las JSP y sobre los servlets.
    <welcome-file-list>
        <welcome-file>guestbook.jsp</welcome-file>
    </welcome-file-list>
Consejo: si utilizas Eclipse, el editor puede abrir este archivo en modo de "diseño". Para modificar este archivo como XML, selecciona la pestaña "Source" (Código fuente) en la parte inferior del marco.
Detén el servidor de desarrollo y, a continuación, inícialo. Consulta la siguiente URL:
La aplicación muestra el contenido de guestbook.jsp, incluido el apodo del usuario si este ha accedido.
Cuando se carga una JSP por primera vez, el servidor de desarrollo la convierte en código fuente Java y, a continuación, compila este código en código de bytes de Java. El código fuente Java y la clase compilada se guardan en un directorio temporal. El servidor de desarrollo vuelve a generar y a compilar las JSP de forma automática si los archivos JSP originales se modifican.
En el momento en que se sube la aplicación a App Engine, el SDK compila todas las JSP en código de bytes y sube únicamente el código de bytes. Cuando la aplicación se ejecuta en App Engine, utiliza las clases JSP compiladas.

El formulario del libro de visitas

La aplicación de libro de invitados necesita un formulario web para que el usuario publique un nuevo saludo, así como una forma de procesar ese formulario. El código HTML del formulario se inserta en la JSP. El destino del formulario es una nueva URL, /sign, que controla una nueva clase de servlet, SignGuestbookServlet.SignGuestbookServlet procesa el formulario y, a continuación, redirecciona el navegador del usuario a /guestbook.jsp otra vez. Por el momento, el nuevo servlet únicamente escribe el mensaje publicado en el registro.
Modifica guestbook.jsp y escribe las líneas que se muestran a continuación justo antes de la etiqueta </body> de cierre:
  ...

  <form action="/sign" method="post">
    <div><textarea name="content" rows="3" cols="60"></textarea></div>
    <div><input type="submit" value="Post Greeting" /></div>
  </form>

  </body>
</html>
Crea una nueva clase llamada SignGuestbookServlet en el paquete guestbook. (Aquellos usuarios que no utilicen Eclipse pueden crear el archivoSignGuestbookServlet.java en el directorio src/guestbook/). Asigna al archivo de origen el siguiente contenido:
package guestbook;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class SignGuestbookServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(SignGuestbookServlet.class.getName());

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        String content = req.getParameter("content");
        if (content == null) {
            content = "(No greeting)";
        }
        if (user != null) {
            log.info("Greeting posted by user " + user.getNickname() + ": " + content);
        } else {
            log.info("Greeting posted anonymously: " + content);
        }
        resp.sendRedirect("/guestbook.jsp");
    }
}
Modifica war/WEB-INF/web.xml y añade las siguientes líneas para declarar el servlet SignGuestbookServlet y para asignarlo a la URL /sign:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    ...

    <servlet>
        <servlet-name>sign</servlet-name>
        <servlet-class>guestbook.SignGuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sign</servlet-name>
        <url-pattern>/sign</url-pattern>
    </servlet-mapping>

    ...</web-app>
Este nuevo servlet utiliza la clase java.util.logging.Logger para escribir mensajes en el registro. Puedes controlar el comportamiento de esta clase a través de un archivo logging.properties y de un conjunto de propiedades del sistema en el archivo appengine-web.xml de la aplicación. Si utilizas Eclipse, tu aplicación se creó con una versión predeterminada de este archivo en el directorio src/ de la aplicación y con la propiedad del sistema adecuada.
Si no utilizas Eclipse, debes configurar el archivo de configuración del registrador de forma manual. Copia el archivo de ejemplo del SDK appengine-java-sdk/config/user/logging.properties en el directorio war/WEB-INF/ de la aplicación. A continuación, modifica el archivo war/WEB-INF/appengine-web.xml de la aplicación tal como se indica:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    ...

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
    </system-properties>
</appengine-web-app>
El servlet registra mensajes a través de un nivel de registro INFO (para lo que utiliza log.info()). El nivel de registro predeterminado es WARNING, que suprime los mensajes INFO del resultado. Para cambiar el nivel de registro de todas las clases del paquete guestbook, modifica el archivo logging.properties y añade una entrada para guestbook.level, tal como se muestra a continuación:
.level = WARNING
guestbook.level = INFO

...
Consejo: si tu aplicación registra mensajes a través del API java.util.logging.Logger mientras se ejecuta en App Engine, App Engine registra los mensajes y los pone a tu disposición para que los explores en la consola de administración y para que los descargues mediante la herramienta AppCfg. La consola de administración te permite explorar los mensajes por nivel de registro.
Vuelve a compilar, reinicia y, a continuación, prueba http://localhost:8888/. Se muestra el formulario. Introduce texto en el formulario y envíalo. El navegador envía el formulario a la aplicación y, a continuación, se redirecciona al formulario vacío. El servidor registra los datos de saludo que introdujiste en la consola.

Siguiente...

Disponemos de una interfaz de usuario en la que se solicita al usuario que introduzca un saludo. Ahora se necesita una forma de recordar los saludos que los usuarios publican para mostrárselos a otros usuarios. Para ello, utilizaremos el almacén de datos de App Engine....si, persistencia de datos en nuestra aplicación!! verán que es fácil , nada de Hibernate, o EJB 3 ...pero bueno, paciencia, y hasta la próxima entrega!
MAriano!

No hay comentarios:

Publicar un comentario