martes, 22 de septiembre de 2009

Manejo de peticiones en Wicket

Cuando Wicket determina que debe manejar una petición, delega su procesamiento a un objeto de tipo RequestCycle. El procesaminto se realiza en 4 pasos consecutivos que se muestran en la siguiente figura (hacer click en la imagen para ver con más claridad):



La gestión de URLs en Wicket es flexible, y en ocasiones, el mismo tipo de petición puede ser codificada de múltiples maneras. Por ejemplo, dependiendo de la configuración, los fragmentos de URL foo=bar, foo/bar y x773s=09is7 pueden significar lo mismo. En el primer paso del manejo de una petición, Wicket decodifica (desempaqueta los valores codificados) la URL de la petición sin importar la forma que tenga, Wicket lo interpreta de una única manera. El resultado de la decodificación es almacenado en un objeto de tipo RequestParameter.

Si observas los valores decodificados del objeto RequestParameter de la figura, puedes suponer qué hace la petición. La ruta de componente 2:actionLink hace referencia al componente con la ruta actionLink, que se encuentra en la página que Wicket conoce mediante el identificador 2. Wicket asigna números de versión cuando se producen cambios estructurales en las instancias de las páginas (por ejemplo, cuando se reemplazan, ocultan o se muestran componentes). En este caso, la versión de la página derivada de la decodificación de la URL es 0, lo que significa que nos encontramos ante la primera (sin modificar) instancia de la página.

En el siguiente paso, Wicket determina el RequestTarget. Wicket puede manejar diferentes tipos de peticiones -por ejemplo, páginas referenciables (el término en inglés es bookmarkable, es decir, páginas a las que podemos acceder poniendo la URL en el navegador), recursos compartidos, y peticiones AJAX. En la figura, la RequestTarget es una instancia de la clase ListenerInterfaceRequestTarget que encapsula la llamada a un enlace (interfaz ILinkListener) de una página previamente renderizada. En este caso, se obtiene la página previamente renderizada usando el identificador 2 y la versión 0, como puedes ver.

El tercer paso, procesamiento de los eventos, es opcional. Se usa para cosas como llamadas a enlaces o a comportamientos Ajax (los componentes en Wicket se pueden extender agregándoles comportamientos), pero no para páginas referenciables o para recursos compartidos. Durante el procesamiento de los eventos, la petición objetivo puede cambiar. Por ejemplo, esto puede ocurrir cuendo se llama a setResponsePage en el método onSubmit de un formulario, en cuyo caso una instancia de PageRequestTarget se usa para el resto del procesamiento de la petición. Llamando a setResponsePage es como más fácilmente se puede navegar de una página a otra cuando se manejan eventos como onClick u onSubmit.

El paso final es responder al cliente. Como ya se ha mencionado, el procesamiento final de una petición se delega al RequestTarget, que es el encargado de crear la respuesta. Un PageRequestTarget se ocupa de renderizar una página y enviarlar al cliente, un ShareResourceRequestTarget se encarga de localizar un recurso (un imagen por ejemplo) y enviarla al cliente, y un AjaxRequestTarget se encarga de renderizar componentes individuales y generar una respuesta XML que la librería Ajax del cliente pueda interpretar

domingo, 20 de septiembre de 2009

Crear un proyecto Wicket

En el siguiente enlace tenemos una utilidad que nos genera el comando para crear un proyecto Wicket con Maven, sólo tendremos que indicar groupId y artifactId de un proyecto con Maven.

Crear un proyecto Tapestry 5 con Maven

1) Hay que ejecutar el siguiente comando:
mvn archetype:generate -DarchetypeCatalog=http://tapestry.formos.com/maven-repository

Al ejecutar este comando en consola, nos pedirá los siguientes parámetros:
  • groupId
  • artifactId
  • version
  • package
Al terminar de generar el proyecto nos creará una carpeta con el nombre indicado en artifactId.
Para preparar el proyecto para Eclipse nos introduciremos en la carpeta del proyecto y ejecutaremos el siguiente comando:

mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true

Ya sólo queda copiar la carpeta creada a nuestra carpeta de proyectos de Eclipse y crear un nuevo proyecto java en eclipse con el mismo nombre. Después de crearlo tendremos que habilitar Maven para el nuevo proyecto.

Para más información visitar el siguiente enlace.

martes, 5 de mayo de 2009

Modelo contextula de componentes en Seam

Jboss-Seam se apoya en este modelo para gestionar los componentes (clases) que forman parte de una aplicación seam. Dicho modelo se puede explicar de la siguiente manera:
  • Seam es una factoría que crea objetos (instancias) según la definición del componente (clase).
  • Después de la creación, cada objeto es almacenado en un contenedor bajo uno de los varios contextos existentes, con distintos tiempos de vida, creando el contexto (scope) de los objetos y capaz de mantener el estado de cada uno.
  • Seam promueve la interacción de estos objetos con estado a través de contextos, ensamblándolos (bijección de dependencias) acorde a los metadatos asociados a sus respectivas clases.
EXPLICACIÓN:

Seam actúa como un contenedor dividido en distintos compartimentos, en cada compartimento se almacenan una serie de componentes. Cada compartimento constituye lo que seam denomina contexto. Un contexto define qué componentes podemos encontrar en él y durante cuánto tiempo. Para ser más precisos, seam gestiona nombres de variables de contexto. Una variable de contexto no es más que una referencia a la instancia de un componente de seam.

¿QUÉ COMPONENTES GESTIONA SEAM Y QUÉ SON?

Jboss-Seam puede gestionar los siguientes componentes:

  • EJB Stateful Bession Beans
  • EJB Stateless Session Beans
  • EJB Message Driven Beans
  • JPA Entity Beans
  • POJO (Plain Old Java Object)
Como podemos ver, un componente en seam no es más que una clase java que se define mediante una programación declarativa (anotaciones, XML), en dicha declaración definimos la variable que accede a una instancia de una clase y su alcance (contexto).

CONTEXTOS EN SEAM

Los contextos están ordenados de menor a mayor duración:

STATELESS

En este contexto no se almacenan las variables. Los componentes en este contexto se instancian cada vez que se resuelve su nombre.

EVENT

Es análogo al scope request de un servlet. La variable existe desde el comienzo de la fase Restore View hasta el final de la fase Render Response del ciclo de vida de una petición en JSF o hasta que se produce una redirección.

PAGE

Comienza al pricipio de la fase Render Response y continua con cada postback JSF hasta que se produce una redirección o se navega a una página distinta.

Aclaración: postback es una acción en una página web en la que se envía una página entera y su contenido al servidor para su procesamiento y éste devulve la misma página (un formulario de logueo por ejemplo). No se debe confundir con actualizar la página.

CONVERSATION

La variable existe desde el final de la fase Restore View hasta el final de la fase Render Response, incluso se se produce una redirección. Si se convierte en una conversación larga (long-running conversation) abarca múltiples peticiones de un mismo usuario hasta que se termina. Las conversaciones se propagan mediante el uso de parámetros especiales de petición para peticiones que no sean postback y a través del árbol de componentes JSF en el caso de peticiones postback.

SESSION

Es análogo al scope session de los servlets. Los accesos a componentes en este contexto son serializados.

APPLICATION

Análogo al scope application de los servlets

BUSINESS PROCESS

Abarca multiples conversaciones de múltiples usuarios. Este contexto se controla de manera declarativa mediante estados de inicio y fin en el fichero de definición del proceso de negocio.

UNSPECIFIED

Es una directiva que indica que el contexto debería ser implícito. Depende de las circunstancias, se le dice a seam para cualquier uso del contexto del componente actual o para ejecutar una búsqueda a través de todos los contextos de manera jerárquica.

CONTEXTOS POR DEFECTO DE LOS COMPONENTES








COMPONENTECONTEXTO
EJB Stateful Session BeanConversation
EJB Stateless Session BeanStateless
EJB Message Driven BeanStateless
JPA Entity BeanConversation
POJOEvent

miércoles, 15 de abril de 2009

Anotaciones para validar Beans en Seam

@Length(min=, max=) Comprueba que la longitud de una cadena se encuentra dentro de un rango
@Max(value=) Comprueba que un valor es menor o igual al indicado
@Min(value=) Comprueba que un valor es mayor o igual al indicado
@NotNull Comprueba que el valor no es nulo
@Past Comprueba que un objeto Date es anterior a la fecha actual
@Future Comprueba que un objeto Date es posterior a la fecha actual
@Pattern(regex=”regexp”, flag=) Comprueba que una cadena cumple el patrón indicado
@Range(min=, max=) Comprueba que un valor está entre el máximo y el mínimo indicado
@Size(min=, max=) En las colecciones, comprueba que el tamaño de la colección se encuentra entre los valores indicados
@AssertFalse Asume que el método devuelve false
@AssertTrue Asume que el método devuelve true
@Valid En coleccuiones o mapas comprueba que todos sus valores son válidos
@Email Comprueba que una cadena cumple con el formato de un e-mail

martes, 14 de abril de 2009

Cambiar puertos en Jboss 5

Para cambiar los distintos puertos que usa jboss 5 por defecto accedemos al fichero:

/jboss-5.x../server/default/conf/bootstrap/bindings.xml


En dicho fichero se pueden cambiar los puertos.

jueves, 5 de marzo de 2009

Formateo de fechas con DateFormat

DateFormat es una clase abstracta de la API estándar de Java que nos permite, entre otras cosas, pasar de objetos Date o Calendar a String con un formato determinado y realizar la operación inversa, crear objetos Calendar o Date a partir de una cadena que contiene la fecha.

De la esta clase hereda otra que realiza las operaciones de manera más sencilla: SimpleDateFormat. En el siguiente ejemplo se ha creado una clase llamada DateFormatter con dos métodos: uno para obtener un objeto Date a partir de un String y otro para realizar la operación inversa.

El patrón MVC

El patrón MVC (Model-View-Controller: Modelo-Vista-Controlador) es un patrón de arquitectura de software que separa el desarrollo de una aplicacíon en tres capas:
  • Modelo: encapsula los datos de la aplicación y la lógica para interactuar con ellos.
  • Vista: maneja la interacción con el usuario y la representación del modelo
  • Controlador: Es el puente entre las dos capas anteriores, se encarga de seleccionar el modelo solicitado por el usuario y seleccionar la vista adecuada para representarlo.
El siguiente diagrama muestra una representación de dicho modelo:



Cada una de estas capas a su vez se puede implementar usando uno o varios patrones de diseño según las necesidades. En el siguiente enlace se muestra una breve explicación de los patrones de diseño más importantes para cada una de las capas.

PATRÓN FRONT CONTROLLER (CONTROLADOR FRONTAL):

Con él se pretende crear un armazón estandar para administrar solicitudes.

El ciclo vital de una solicitud a través de un controlador frontal sigue los siguientes pasos:

  • El usuario emite una solicitud al controlador de la aplicación
  • La solicitud se divide en parámetros de formulario
  • La solicitud se autentifica
  • La acción solicitada se mapea a un recurso específico
  • Se crea un objeto de comandos para procesar la solicitud
  • La solicitud se envía a la página adecuada
  • La salida de la acción solicitada se muestra al usuario

ESTRATEGIAS:

1) AYUDA DE SOLICITUD: Esta estrategia implementa una clase que recibe como parámetro la solicitud y la procesa pudiendo realizar las funciones de autentificación de la solicitud (se comprueba que se ha recibido los parámetros esperados) y se mapea al objeto de comandos que realiza las operaciones solicitadas (nos devuelve el objeto Action).

2) CONTROLADOR Y COMANDO: Se crea un objeto comando que realiza las operaciones solicitadas. Nuestro objeto comando es el encargado de obtener el modelo, realizar las operaciones necesarias sobre el mismo y seleccionar la vista que va a representar el modelo.

PATRÓN DECORATING FILTER (FILTRO DECORADOR):

Este patrón nos permite modificar la solicitud antes de ser entregada al controlador correspondiente y modificar la respuesta antes de ser entregada al cliente. Entre los posibles usos de los filtros podemos destacar:

  • Registrar información importante sobre cada solicitud
  • Autentificar usuarios
  • Transformar los datos de entrada antes del procesamiento
  • Transformar los datos de la respuesta para un dispositivo específico
  • Validar los datos del formulario e interrumpir el procesamiento si fuera necesario
PATRÓN VIEW HELPER (AYUDANTE DE VISTA):

Este patrón especifica que se utilicen helpers para adaptar los datos del modelo a la capa de presentación de una aplicación. Estos helpers consisten en librerías de etiquetas (creadas por el propio programador o utilizando etiquetas proporcionadas por algún framework) o JavaBeans o ambos.

lunes, 9 de febrero de 2009

Atajos de teclado en Eclipse II

  • May+Alt+L: crea una variable que almacena el valor de retorno de un método
  • Ctrl+May+T: abre un cuadro de diálogo para abrir un tipo (clase, interfaz,...)
  • Ctrl+May+R: abre un cuadro de diálogo que nos permite abrir un fichero
  • Ctrl+May+flecha arriba o abajo: nos permite copiar la línea en la que está el cursor
  • Ctrl+D: elimina la línea en la que está el cursor
  • Alt+flecha arriba o abajo: mueve la línea en la que está el cursor
  • Ctrl+7: añade la dobre barra de comentario en la línea en la que está el cursor

Uso de la herramienta de Log de Apache

Apache nos ofrece dos librerías para hacer log de nuestras aplicaciones en consola con funcionalidades más amplias al típico System.out.println().

Introducción a las pruebas con TestNG

Como realizar pruebas con este framework

Introducción al modelo de aplicaciones web en capas

Este modelo divide nuestra aplición en distintas capas que se encargan de distintos aspectos. La siguiente figura muestra este modelo:

Organización de las clases en paquetes

Las clases que conforman nuestra aplicación deberían estar organizadas en paquetes según funcionalidades comunes. En la siguiente figura se muestra un esquema de ello:

Introducción a JSP (Java Server Pages)

Las JavaServer Pages (JSP) nos permiten separar la parte dinámica de nuestras páginas Web del HTML estático. Básicamente, conseguimos incrustar código java dentro de un documento HTML cuya extensión ha de ser *.jsp.
Hay tres tipos de construcciones JSP que embeberemos en una página: elementos de script, directivas y acciones. Los elementos de script nos permiten especificar código Java que se convertirá en parte del servlet resultante, las directivas nos permiten controlar la estructura general del servlet, y las acciones nos permiten especificar componentes que deberían ser usuados, y de otro modo controlar el comportamiento del motor JSP. En el siguiente enlace podemos ver una tabla detallada de estas construcciones.
En el modelo MVC, JSP conformaría la vista de nuestra aplicación. En el siguiente tutorial se muestra más detalladamente la especificación JSP:
- Tutorial Servlets y JSP

Patrón de diseño Controlador Frontal

¿QUÉ ES UN PATRÓN DE DISEÑO?

Los patrones del diseño tratan los problemas del diseño que se repiten y que se presentan en situaciones particulares del diseño, con el fin de proponer soluciones a ellas. Por lo tanto, los patrones de diseño son soluciones exitosas a problemas comunes.

¿QUÉ ES EL PATRÓN CONTROLADOR FRONTAL (FRONT CONTROLLER)?

Es un patrón de diseño que se basa en usar un controlador como punto inicial para la gestión de las peticiones. El controlador gestiona estas peticiones, y realiza algunas funciones como: comprobación de restricciones de seguridad, manejo de errores, mapear y delegación de las peticiones a otros componentes de la aplicación que se encargarán de generar la vista adecuada para el usuario. La siguiente figura muestra un esquema de ello:



Ventajas:
  • Tenemos centralizado en un único punto la gestión de las peticiones
  • Aumentamos la reusabilidad de código
  • Mejoramos la gestión de la seguridad
Desventajas:
  • La velocidad de respuesta disminuye al tener que ser procesadas las peticiones primero por el controlador.
En el siguiente enlace se puede ver una explicación más detallada de este patrón.

jueves, 5 de febrero de 2009

Principios POO

En este artículo resumo cinco principios básicos de la programación orientada a objetos:

  • Responsabilidad única
No debe existir más de una razón para cambiar una clase.
  • Abierto / Cerrado
Los artefactos software deben ser abiertos para su extensión, pero cerrados ante una modificación.
  • Sustitución
Toda clase debe poder ser reemplazada por cualquiera de sus subclases

  • Inversión de dependencia
Los módulos de nivel superior no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.
  • Segregación de Interface
Los clientes no deben ser forzados a depender de interfaces que no utilizan.

En los siguientes enlaces se encuentran explicaciones más detalladas a cerca de estos principios
-Principios POO 1
-Principios POO 2

miércoles, 4 de febrero de 2009

Instalación de testNG en Eclipse

¿QUÉ ES TESTNG?

TestNG es un framework para pruebas y testing que nos permite desarrollar nuestro proyectos usando TDD (Test Driven Development -desarrollo guiado por pruebas). Esta técnica de desarrollo se podría resumir en los siguientes pasos:
  • Se crea una prueba unitaria
  • Se verifica que falle
  • Se implementa el código que hace que la prueba no falle
  • Se verifica que no falle
  • Se refactoriza el código
TRABAJAR CON TESTNG EN ECLIPSE

Para descargar el proyecto:
Para instalar el plugin en Eclipse:
  • Abrimos Help->Software Updates
  • Pulsamos sobre Add Site...
  • En el diálogo escribimos la dirección http://beust.com/eclipse
  • Seleccionamos el nuevo sitio y pulsamos sobre Install
  • Seguimos el asistente de instalación
  • Reiniciamos Eclipse
Para crear un proyecto con testNG:
  • Descomprimimos el *.zip del proyecto en nuestra carpeta de trabajo de Eclipse
  • Creamos un nuevo proyecto, por ejemplo, un proyecto java
  • Le damos el nombre, por ejemplo, testeo y pulsamos siguiente
  • Creamos dos nuevas carpetas de fuentes pulsando sobre Create new source folder: a una la llamamos java/src y a la otra java/test. Lo importante es que ambas carpetas tengan la misma raíz, es decir, java (o el nombre que elijamos).
  • En la pestaña Libraries del mismo cuadro de diálogo pulsamos sobre Add External JARs...
  • En el cuadro de selección de ficheros nos dirigimos a la carpeta del proyecto testng que está en la carpeta workspace de Eclipse y seleccionamos el fichero testng-5.8-jdk15.jar
  • Pulsamos sobre finalizar
  • En nuetro nuevo proyecto, dentro de la carpeta java/src creamos un nuevo paquete, por ejemplo, es.cea y dentro de la carpeta java/test creamos exactamente el mismo (es.cea). Es muy importante que ambas carpetas el nombre del paquete sea el mismo
Para abrir la perspectiva TestNG:
  • Pulsamos sobre Window->Show View->Other...
  • En el campo de texto del diálogo que nos aparece, escribimos testng y nos debe aparecer la vista
  • La seleccionamos y listo
Para lanzar un test:
  • Seleccionamos la clase que queremos comprobar
  • Abrimos el menú contextual y seleccionamos Run As->TestNG Test

martes, 3 de febrero de 2009

Evitar recorrer listas con bucles implementando el método equals()

Cuando tenemos una lista de objetos y necesitamos comprobar que un elemento existe en ella podemos resolverlo creando un bucle(for,while,..) junto con una sentencia if que compruebe en cada iteración si el objeto existe. Una opción a esto consiste en lo siguiente:
  • Sobreescribir el método equals() de la clase de dicho objeto y establecer qué atributos se tienen en cuenta a la hora de comparar.
  • Instanciar un objeto de dicha clase con los mismos valores que el que buscamos
  • Usar el método contains(Object o) de la lista con el objeto que hemos creado para comprobar si existe uno igual
En este enlace se muestra el código de dos clases: Agenda y Persona. La clase Agenda posee un atributo de tipo List que guarda la lista de personas y posee dos métodos para comprobar si existe un elemento en la lista. El primero, existeModo1(), utiliza un bucle for para hallar el elemento y el segundo, existeModo2(), utiliza el método contains().

Métodos forward(), include(),init() y sendRedirect()

INTRODUCCIÓN

Un servlet/JSP puede invocar de modo directo a un recurso de la web. La idea es poder reenviar la petición (request) a dicho recurso. Para hacer esto necesitamos un RequestDispatcher, que es un referencia que encapsula el recurso. En el siguiente ejemplo (véase la clase PruebaDispatcher) el servlet tiene como "dispatcher" otro servlet (sc es un ServletContext que se obtiene en init()):

RequestDispatcher dispatcher = sc.getRequestDispatcher("/requestimagen");


Observar que el argumento corresponde con el url-pattern de web.xml. La creación del dispatcher se podría escribir de otra forma:

ResquestDispatcher dispatcher = request.getRequestDispatcher("/requestimagen");

Pero se puede observar que este método en ocasiones falla y la documentación de Sun recomienda la primera forma: sc.getRequestDispatcher(arg). El argumento es la ruta del recurso, que debe comenzar con "/" y es interpretado como relativo al contexto actual. Conviene usar getContext() para obtener un RequestDispatcher de recursos en contextos externos.
getRequestDispatcher(arg) retorna null si el ServletContext no puede retornar un RequestDispatcher.

La invocación al recurso se puede hacer de dos formas:
  • Incluir el recurso en el flujo de salida. La salida de "/requestimagen" se incluye en la salida del primer servlet.
dispatcher.include(request, response);
  • Redirigir (forward) la petición al recurso. Funcionalmente semejante a sendRedirect(). Se trata de redirigir la petición a otro componente:
dispatcher.forward(request, response);

La diferencia entre sendRedirect() y forward() (o también include()) es:
  • En sendRedirect() la petición acaba bajo el control del segundo servlet. La URL que se puede ver en el navegador es la del segundo servlet. Además sendRedirect() es un método de HttpResponse
  • En forward() o include() la petición se controla por el primer servlet. La URL que se puede ver en el navegador es la del primer servlet.
Aquí se puede ver el código de las clases PruebaDipatcher y RequestImagen.

viernes, 30 de enero de 2009

Manejo de fechas

La API de java nos provee de dos clases para manejar fechas: Date y Calendar, ambas en el paquete java.util. Calendar ofrece más opciones y Date está en desuso.

Crear un objeto Calendar:

Calendar cal=Calendar.getInstance();

Esto nos crea un objeto Calendar con los datos del sistema. Para obtener los ditintos campos utilizamos el método get(int field) que nos devuelve un entero. La clase Calendar posee atributos estáticos que representan los distintos campos de una fecha:

cal.get(Calendar.DATE):devuelve el día
cal.get(Calendar.MONTH):devuelve el mes
cal.get(Calendar.YEAR):devuelve el año

Modificar un objeto Calendar:

Para ello recurrimos al método set(int field). Al igual que con get(int fiel) le pasamos como parámetro el campo que queremos modificar. Si lo que queremos es sumar una cantidad a uno de los campos podemos recurrir al método roll(int field,int cantidad), por ejemplo:

cal.roll(Calendar.DATE, -5): resta 5 días.
cal.roll(Calendar.MONTH, 5): suma 5 meses.

Formatear fechas:

Para formatear fechas podemos recurrir a la clase SimpleDateFormat del paquete java.text. El siguiente ejemplo nos muestra cómo usar dicha clase para darle formato a una fecha:

SimpleDateFormat formater=new SimpleDateFormat();
formater.applyPattern("dd/MM/yy");
String fechaFormateada=formater.format(cal.getTime());

¡¡Ojo!!:

La clase Calendar le asigna el valor 0 al mes de enero y no 1, esto hay que tenerlo en cuenta a la hora de manejar fechas



martes, 27 de enero de 2009

Instalacion del plugin SVN en Eclipse

¿QUÉ ES SVN?

SVN es un sistema de control de versiones que nos permite tener un historial de los distintos cambios que hacemos sobre nuestro código y, por tanto, mantener guardado en un lugar centralizado las distintas versiones de nuestros proyectos.

INSTALACIÓN DEL CLIENTE SVN EN ECLIPSE
AGREGAR UN REPOSITORIO
  • Abrimos la vista de SVN: Window->Show View y escribimos SVN
  • En el panel SVN Repositories: Menú contextual->New->Repository Location...
  • Introducimos la URL del repositorio y aceptamos
DESCARGAR UN PROYECTO DE UN REPOSITORIO
  • En la vista Project Explorer: Menú contextual->New->Project
  • En el nuevo diálogo elejimos SVN->Checkout Projects from SVN
  • En el siguiente diálogo seleccionamos el repositorio del que queremos descargar
  • Elejimos el proyecto y aceptamos
  • En el siguiente diálogo elejimos el nombre para el proyecto
SUBIR UN PROYECTO A UN REPOSITORIO
  • En la vista Project Explorer seleccionamos el proyecto: Menú contextual->Team->Share Project...
  • En el siguiente diálogo seleccionamos el sistema de versiones SVN.
  • Seleccionamos el repositorio
  • En el siguiente diálogo seleccionamos el nombre para el proyecto y aceptamos
  • Una vez creado nos vamos al proyecto: Menú contextual->Team->Commit...
SUBIR UN PROYECTO A UN REPOSITORIO DISTINTO
  • Sobre el proyecto: Menú contextual->Team->Disconnect...
  • Seguimos los pasos para subir un proyecto

viernes, 23 de enero de 2009

Limpiar la caché del servidor

Cuando estamos realizando muchos cambios en nuestro código, es aconsejable limpiar la caché del servidor de manera eventual porque puede que no esté actualizando dichos cambios y nos lleve a situaciones en las que nuestra aplición no se ejecute como se podría esperar.

jueves, 22 de enero de 2009

Filtros

¿QUÉ SON LOS FILTROS?

Los filtros son clases que nos permiten realizar ciertas operaciones sobre una petición (HttpServletRequest) antes de ser entregada al servlet destino y de la misma manera nos permite realizar ciertas operaciones sobre la respuesta (HttpServletResponse) de un servlet antes de ser entregada al cliente. La siguiente figura nos muestra dicho proceso:



Hay que tener en cuenta que:
  • Podemos tener más de un filtro para procesar la petición dispuestos en cadena
  • Un mismo filtro puede atender las peticiones de más de un servlet
  • Un filtro puede procesar únicamente la petición o únicamente la respuesta
¿QUÉ ACCIONES PODEMOS REALIZAR EN UN FILTRO?

Los filtros nos pueden permitir verificar los datos que el usuario envía a la aplicación, darle un formato determinado a esos datos, desviar la petición a otro servlet para que la procese antes de enviar la información al servlet destino, darle formato a la respuesta que envía el servlet, modificar convenientemente la respuesta de un servlet (por ejemplo una imagen, un fichero pdf, etc), etc. Hay dos importantes ventajas que nos ofrecen los filtros:
  • Descarga al servlet de realizar ciertas tareas relacionadas con la petición y la respuesta
  • Si está adecuadamente diseñado, nos permite reutilizar ese filtro en distintas aplicaciones
¿CÓMO SE CREA UN FILTRO?

  • Creamos una clase que implemente la interfaz javax.servlet.Filter
  • Implementamos sus métodos
  • Damos de alta el filtro en el fichero web.xml

miércoles, 21 de enero de 2009

Uso de Listeners

¿QUÉ ES UN LISTENER?

Un Listener (o escuchador) es una clase que implementa la interfaz Listener y que nos permite realizar ciertas acciones ante un evento determinado. Los eventos que atiende un escuchador son:
  • Cuando se inicia la aplicación (se crea el objetos ServletContext) y cuando se termina
  • Cuando se inicia una sesión (se crea un objeto HttpSession) y cuando se cierra
  • Cuando se realiza una petición (se crea un objeto HttpServletRequest) y cuando se destruye
La siguiente figura muestra el evento que produce cada objeto y el escuchador que atiende a dicho evento:



¿QUÉ ACCIONES PODRÍAMOS REALIZAR ANTE ESTOS EVENTOS?

Los escuchadores nos permiten inicializar las varibles de aplicación comunes a todos los usuarios (ServletContextListener), inicializar variables de sesión para un usuario (HttpSessionListener), hacer comprobaciones sobre los datos que el usuario envía a la aplicación (ServletRequestListener) o cualquier otra acción que necesitemos.

¿CÓMO SE CREA UN LISTENER?

  • Creamos una clase que implemente la interfaz Listener
  • Implementamos sus métodos
  • Lo damos de alta en el fichero web.xml

Esctructura de directorios de una aplicación web

Una aplicación web desarrollada en java tiene una estructura similar a la siguiente:

aplicacion/
.../archivo.html
.../archivo.jsp
.../img/archivo.png
.../css/archivo.css
.../html/otro.html
.../jsps/otro.jsp
-------------------------------------------------------
Las carpetas y documentos anteriores conforman el contenido accesible desde el navegador
-------------------------------------------------------
.../WEB-INF/web.xml(Archivo de despliegue de la aplicaión)
.../WEB-INF/classes/es.cea...(Aquí van las clases de nuestra aplicación)
.../WEB-INF/lib/libreria.jar(Aquí van las librería necesarias para la aplicación)

Colecciones de objetos

Java nos provee de distintos tipos de estructuras para almacenar colecciones de objetas y poder operar sobre dichas colecciones. Entre los más importantes nos encontramos con las listas (List), los mapas (Map) y los conjuntos (Set). Los conjuntos se diferencian de los otros dos en que no pueden tener elementos duplicados (aquí entra en juego la sobreescritura del método equals() para determinar la duplicidad de los objetos).
En los servlets podemos usar el método println(variable_estructura) para imprimir todos los objetos que contiene la estructura (aquí interviene la sobreescritura del método toString() de los objetos almacenados). La forma en que se imprimen es entre corchetes y separados por comas los distintos objetos:

[objeto1,objeto2,...,objetoN]

martes, 20 de enero de 2009

Introducción a las sesiones en los Servlets

Para poder obtener un objeto HttpSession recurrimos al método getSession() del objeto HttpServletRequest. De este modo podemos crear variables de sesión mediante el método setAttribute(clave,valor) del objeto HttpSession y acceder a esas variables con el método getAttribute(clave). El método getAttribute(clave) devuelve un objeto de tipo Object así que es necesario hacer casting al tipo adecuado cuando recuperamos la variable. Ejemplo:

HttpServletRequest req;
req.getSession().setAttribute("nombre","raul"); //Declaramos la variable de sesión
String nombre=(String)req.getSession().getAttribute("nombre"); //Recuperamos la variable

Atajos de teclado en Eclipse I

Eclipse nos provee de una serie de atajos de teclado que facilita nuestro trabajo
  • Ctrl+1 sobre un elemento del código (variable, método, atributo, clase,...) nos ofrece sugerencias sobre él.
  • Escribir syso y después teclear Ctrl+Espacio nos genera la instrucción System.out.println
  • Si pulsamos Ctrl+click sobre cualquier elemento del código nos permite navegar por el código como si de una página web se tratase. Por ejemplo, si hacemos esta operación sobre una variable de tipo Persona declarada en una clase Agenda nos llevaría al código de la clase Persona. Con Alt+flecha izquierda volvemos al código donde ejecutamos Ctrl+click.
  • Si estamos tecleando código y pulsamos Ctrl+Espacio nos aparece el diálogo de sugerencia de código para poder autocompletar.

Sobreescritura de métotos desde Eclipse

Eclipse nos provee de las opciones necesarias para sobreescribir o implementar ciertos métodos. Siguiendo con la línea de la anterior entrada, podemos sobreescribir los métodos toString() y equals(Object) de la siguiente manera:
  • Elegimos la opción Source->Override/Implements Methods...
  • En el diálogo que nos aparece elegimos los métodos que queremos sobreescribir
  • Nos aparece el código de los métodos elegidos y sólo queda implementar el código
En el caso del método equals(Object) tenemos una opción aún mejor:
  • Elegimos la opción Source->Generate hashCode() and equals()...
  • En el diálogo elegimos los atributos que servirán de criterio para la igualdad
  • Se genera en nuestra clase los métodos correspondientes y su código.
Otras dos opciones muy útiles del menú Source son:
  • Generate Getters and Setters...
  • Generate Constructor using Fields...
La primera opción nos genera el código de los métodos getAtributo()-setAtributo() para cada uno de los atributos que le indiquemos en el cuadro de diálogo que se nos muestra. En el segundo caso se nos genera el código de un constructor que inicializa los atributos que le indiquemos en el cuadro de diálogo que nos aparece.

Sobreescritura de métotos heredados de Object

Todas las clases en Java (incluidas las que creamos nosotros) heredan implícitamente de la clase Object. De esta clase heredamos los siguientes métodos:
  • toString()
  • equals(Object)
  • hashCode()
  • finalize()
  • clone()
De los métodos antes mencionados es interasante la sobreescritura de dos de ellos. Al igual que imprimimos un String o cualquier variable primitiva en pantalla, podemos imprimir un objeto. Cuando imprimimos un objeto lo que ocurre es que se llama al método toString() del objeto y se imprime la cadena que este método nos devuelve. Según como esté implementado, la salida será una u otra. Por defecto este método imprime en pantalla la clase a la que pertenece el objeto y la dirección de memoria del mismo en el siguiente formato:

paquete.Clase@direccion

En el caso de las clases de envoltorio este método está sobreescrito para que muestre una cadena con el valor primitivo que encapsula. En nuestras clases podemos sobreescribirlo para que muestre el valor de los atributos que nos interese mostrar en vez de recurrir a métodos getVariable() y tener que transformar la salida en un String. En este ejemplo lo vemos:

public class Persona{
private String nombre;
private Integer edad;
public Persona(String n,Integer e){
nombre=n;
edad=e;
}
@Override
public String toString(){
return "NOMBRE: "+nombre+"\nEDAD: "+edad;
}
public static void main(String[] args){
Persona p1=new Persona("Pepe",new Integer(30));
System.out.println(p1);
}
}


La salida de la anterior clase nos daría como resultado:

NOMBRE: Pepe
EDAD: 30

En el caso de las colecciones de objetos, esto nos permitiría recorrer la colección e imprimir el valor de las variables con sólo llamar a nuestro método toString() sobreescrito.

El otro método que nos puede interesar sobreescribir es el método equals(Object). Este método compara dos objetos y nos devulve true o false en caso de que sean iguales o no. Según como esté implemetado el método en cada clase, los criterios de igualdad variarán. Nos puede interesar en las clases que creamos determinar los criterios a tener en cuenta para establecer esa igualdad sobreescribiendo el método equals(Object). Siguiendo con el ejemplo anterior:

public class Persona{
private String nombre;
private Integer edad;
public Persona(String n,Integer e){
nombre=n;
edad=e;
}
@Override
public String toString(){
return "NOMBRE: "+nombre+"\nEDAD: "+edad;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (nombre == null) {
if (other.nombre != null)
return false;
} else if (!nombre.equals(other.nombre))
return false;
return true;
}
public static void main(String[] args){
Persona p1=new Persona("Pepe",new Integer(30));
Persona p2=new Persona("Pepe",new Integer(25));
boolean igual=p1.equals(p2);
System.out.println(p1);
System.out.println(p2);
System.out.println("\nEs igual: "+igual);
}
}


El ejemplo anterior nos devolverá que la variable igual es true ya que el criterio de igualdad que hemos definido es el atributo nombre:

NOMBRE: Pepe
EDAD: 30
NOMBRE: Pepe
EDAD: 25

Es igual: true



sábado, 17 de enero de 2009

Imprimir variables en JSP

JSP nos permite incrustar código java en cualquier parte dentro de un documento con etiquetas HTML. Para ello debemos encerrar dicho código entre las etiquetas <% %>. Si queremos imprimir el valor de una variable en un punto determinado los hacemos de la siguiente manera:

<%=variable%>

Pero hay una restricción a ello, la variable debe ser un String. Si queremos imprimir el valor de una variable de tipo primitivo debemos primero hacer boxing-encapsular el valor dentro de su clase envoltorio correspondiente- y después usar el método toString() para convertirlo en una cadena.

¡¡Truquito!!
Para ahorrarnos los pasos anteriores podemos sumarle a la variable el valor de una cadena vacía ya que el resultado de esta operación devuelve un String:

<%=variable+""%>

viernes, 16 de enero de 2009

Introducción a los Servlets

Un servlet no es más que una clase java capaz de procesar peticiones http por parte de un cliente. Para crear un servlet seguimos los siguientes pasos:

1- En Eclipse, dentro de nuestra aplicación web, en JavaResources: src creamos un nuevo paquete y le damos el nombre que queramos p.e. es.cea
2- Dentro de ese paquete creamos nuestra clase Servlet p.e. Saludo
3- Esa clase debe heredar de HttpServlet y sobreescribir los métodos doGet() y doPost(). Estos métdos se encargan de realizar las operaciones necesarias como respuesta a la solicitud.

¡¡Truquito!!
Cuando heredamos una clase o implementamos una interfaz, podemos ahorrarnos escribir el código de los miembros que queremos sobreescribir de la siguiente manera.
- Abrimos el menú contextual dentro del cuerpo de la declaración de la clase
- Elegimos la opción Source->Override/Implements Methods
- Nos sale un cuadro de diálogo con todos los métodos disponibles
- Marcamos los que queremos implementar y aceptamos
- Ahora aparce en nuestra clase el código con los métodos.

4- Editamos el fichero web.xml de nuestra aplicación y damos de alta nuestra clase en Tomcat.

jueves, 15 de enero de 2009

Procesar peticiones en JSP

CREAR PROYECTO DE TRABAJO

Para la clase de hoy se creará un nuevo proyecto en Eclipse:
1- Crear un nuevo proyecto web dinámico llamado cea01.
2- Creamos dentro de WebContent el fichero bienvenida.jsp
3- Desplegamos el fichero en Tomcat
4- Accedemos a la URL http://localhost:8090/cea01/bienvenida.jsp para comprobarlo.

TEORIA: OBJETOS IMPLÍCITOS EN JSP Y SERVLETS



Los objetos mostrados en la anterior tabla son implícitos ya que no es necesario instanciarlos, la máquina virtual se encarga de ello, y así podemos hacer un uso directo de sus métodos y atributos. Cada uno de esos objetos se utilizan dentro de un contexto:

A) EVENTO

Un evento es toda acción que el usuario realiza sobre nuestra página y que genera URL más sus parámetros (si los hay), es decir, pulsar sobre un botón, un enlace, escribir directamente una URL, enviar un formulario,etc. Los eventos son manejados en JSP mediante el objeto request. El esquema siguiente muestra dicho proceso:




De esta manera, cada vez que se genera un evento, se crea un nuevo objeto request que se encarga de procesar dicho evento y que se destruye en el momento que procesa los datos que recibe. Para procesar los datos tenemos dos métodos:

-String getParameter(String parámetro): nos devuelve el valor del parámetro indicado
-String getRequestURL(): nos devuelve la URL que recibe los parámetros(el fichero)

Para entender estos dos métodos hay que tener en cuenta que el formato de petición de una URL con parámetros es: url_destino?parametro1=valor1&parametro2=valor2&... Por ejemplo:
bienvenida.jsp?nombre=raul&edad=27. Usando los dos métodos mencionados obtendríamos:

getParameter(“nombre”) devuelve “raul”
getParameter(“edad”) devuelve “27”
getRequestURL() devuelve “bienvenida.jsp”



B) SESIÓN

Este contexto se produce desde que un usuario accede a nuestra aplicación hasta que la abandona. Las sesiones son procesadas en JSP mediante el objeto session. Por tanto, se creará un nuevo objeto session por cada usuario que acceda a la aplicación y se destruirá dicho objeto cuando el usuario abandone la aplicación. Con respecto a esto hay que tener en cuenta que si un usuario accede a una aplicación desde dos navegadores distintos se crean dos sesiones ya que el usuario de nuestra aplicación es el programa navegador y no la persona que lo utiliza. En resumen, el objeto session nos permite encapsular aquellos recursos que podamos necesitar durante la sesión. Para ello tenemos los siguientes métodos:

-void setAttribute(String clave,String valor): definimos un parámetro y su valor
-String getAttribute(String clave): obtenemos el valor de un parámetro

C) APLICACIÓN

Este contexto se produce por la propia aplicación en sí y se mantiene mientras la aplicación se ejecute en el servidor. Por tanto, sólo hay un objeto application por cada aplicación. Este objeto encapsula todos los recursos necesarios durante la ejecución de nuestro programa.

EN RESUMEN:

- Los recursos comunes a todos los usuarios son manejados por application
- Los recursos comunes a un usuario durante su sesión son manejados por session
- Los recursos propios de un evento son manejados por request
- Sólo hay un objeto application por cada aplicación
- Hay un objeto session por cada usuario de la aplicación
- Se genera un objeto request por cada evento

miércoles, 14 de enero de 2009

Instalación de herramintas

1- Creación del presente blog desde blogger.com. La direccion del blog es
raultinoco-cea2.blogspot.com.

2- Crear una cuenta en del.icio.us para gestionar marcadores y hacer seguimiento de los distintos enlaces que visitamos cuando investigamos a cerca de un tema. La cueanta creada es ul2mac.

3- Crear un sistema de subversión en code.google.com para poder subir el código de los ejercicios propuestos. Para ello sólo es necesario tener una cuenta con gmail. El sistema de subversión creado es raultinoco-cea2.

4- Instalación de Apache Tomcat 6.0: para ello se ha creado una carpeta servers dentro de la carpeta JAVA y en su interior se ha descomprimido la estructura de ficheros de Tomcat. Posteriormente se ha creado el usuario "tomcat" con el "manager" editando el fichero tomcat-users.xml de la carpeta conf en el directorio de Tomcat y se ha añadido la variable de entorno JAVA_HOME con la URI de la carpeta donde se encuentra Tomcat.

5- Instalación del IDE eclipse. Para ello se siguieron los siguientes pasos:
a) Descomprimir en la carpeta JAVA el fichero con la estructura de directorios de dicho IDE.
b) Crear la carpeta C:\workspace.
c) La primera vez que abrimos eclipse asignamos la carpeta anterior como carpeta de trabajo
por defecto y activamos la casilla para que no vuelva a preguntar el espacio de trabajo.

6- Agregar en Eclipse el servidor web Apache Tomcat. Para ello se siguieron los siguientes pasos:
a) Abrir eclipse.
b) Agregar la vista de servidores: Window->Show View->Servers.
c) Dentro de la pestaña Servers que ahora nos aperece abrir el menú contextual y seleccionar:
New->Server.
d) En el nuevo cuadro de diálogo elegir Apache->Tomcat v6.0 Server y pulsar siguiente.
e) En el nuevo cuadro de diáogo indicar la ruta donde se encuntra Tomcat, en nuestro caso
está en C:\...\JAVA\servers\apache-tomcat-6.0.18.
f) Cambiar el JRE con el que trabajamos por JDK. Para ellos pulsamos sobre Installed JREs,
en el nuevo diálo pulsamos sobre Add, en el nuevo diálogo elegimos Standard VM y
pulsamos siguiente, seleccionamos la ruta del JDK: C:\Archivos de Programas\Java\jdk-xx,
le damos a aceptar y seleccionamos el JDK como JRE por defecto.
g) Ya nos aparece en la vista Servers nuestro Tomcat. Para iniciarlo abrimos el menú
contextual sobre él y pulsamos Start.

7- Instalación del plagin JBoss en eclipse. Para ello descomprimimos el fichero. Nos aparecen dos carpetas: plugins y features. El contenido de plugins lo copiamos al directorio plugins de eclipse y el contenido de featrues lo copiamos dentro del directorio features de eclipse. Arrancamos eclipse y comprobamos en Window->Show View->Other que nos aparece JBoss.

8- Crear el proyecto holaMundo en eclipse y desplegarlo en Tomcat. Para ello:
a) Pulsamos sobre File->New->Dynamic Web Project.
b) En el diálogo le damos el nombre holaMundo y en la sección Target Runtime
seleccionamos Apache v6.0 Tomcat. Pulsamos siguiente.
c) En el siguiente diálogo dejamos los valores por defecto y pulsamos sobre finalizar
d) En la vista Project Explorer de la ventana principal desplegamos el árbol de directorios de
nuestro proyecto y sobre la carpeta WebContent abrimos el menú contextual y elegimos
New->JSP. En el cuadro de diálogo le damos el nombre index y aceptamos.
e) Se nos abre el fichero e introducimos el código JSP.


f) Para desplegar nuestro proyecto abrimos el menú contextual sobre el servidor Tomcat y
seleccionamos Add and Remove Projects. En el nuevo diálogo elegimos el proyecto que
hemos creado lo añadimos y aceptamos.
g) Para ver el proyecto abrimos el explorador he introducimos la ruta siguiente:
http://localhost:8080/holaMundo/index.jsp?nombre=loquesea.