Ejemplo de web con ICEfaces
En
Autentia nos gusta aprender y
trabajar con las últimas tecnologías, y en este
tutorial os presentamos un
ejemplo sencillo pero práctico de ICEfaces con
JSF. Es recomendable que lo sigas
paso a paso, no te importe el tiempo que dediques (según el
nivel inicial que
tengas). Seguro que aprenderás cosas nuevas, y sobre todo,
te divertirás al ver
los resultados. ¡Comencemos!
Introducción
La combinación JEE-Ajax
están en constante evolución, y en
este tutorial vamos a ver un ejemplo paso a paso de cómo
sacar partido a ambas
cosas usando Icefaces 1.6. ICEfaces es un proyecto open source de
ICESoft
Tecnologies que ofrece medio centenar de componentes JSF, Ajax basado
en
servidor, y sus fundamentos lo sitúan
como un framework muy a tener en cuenta
para nuestros desarrollos en Java con características
visuales avanzadas:
·
El uso de Ajax es transparente para el
programador. Introducir
los componentes disponibles en nuestro código cliente y
listo!
·
Compatibilidad 100% con los
estándares Java.
·
De todos los frameworks Ajax del mercado,
ICEfaces destaca
especialmente por su seguridad y compatibilidad con servidores de
aplicaciones
Java, IDEs, componentes de terceros y librerías de
javascript.
En el tutorial https://adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=tomcat6_icefaces
podrás encontrar información ampliada,
así como en la página del proyecto www.icefaces.org.
Manos a la obra.
Partiremos del
siguiente entorno:
·
Distribución de binarios de
ICEfaces 1.6.2 (sección de descargas
de icecafes.org).
·
Apache ant 1.7.0
·
Apache Tomcat 5.5
·
Un IDE, como por ejemplo, Eclipse 3.3.
ICEfaces.org ofrece un
plugin para Eclipse y un buen consejo es instalarlo si se quiere
profundizar
con ICEfaces. Para nuestra aplicación no es necesario un
IDE, pero nos facilita
la codificación, depuración y control de
dependencias.
El ejercicio
práctico consiste en una página web que permita
realizar búsquedas en un
catálogo, y dar altas al mismo. En sí no parece
nada innovador, pero veremos
cómo ICEfaces va a dar mucho juego con poco
código 🙂 La temática será la
astronomía
y el catálogo será de estrellas, si bien puedes
adaptarlo a tus gustos casi de
manera inmediata.
Comenzamos dando de
alta un proyecto Java en Eclipse, TutorialIcefaces, y creamos la
siguiente
estructura de directorios:
src y la JRE la
proporciona el propio eclipse. A nivel raíz del proyecto
creamos lib y web.
Como carpetas hijas de web, img, META-INF y WEB-INF. Y dentro de
WEB-INF,
resources.
Creamos
el web.xml
bajo WEB-INF con la configuración del proyecto para integrar
ICEfaces, mapear
los servlets, etc.
<?xml version=«1.0»?>
<!DOCTYPE web-app PUBLIC «-//Sun Microsystems, Inc.//DTD Web Application «http://java.sun.com/dtd/web-app_2_3.dtd»>
<web-app>
<context-param> </context-param>
<context-param> </context-param>
<context-param> </context-param>
<context-param> </context-param> <!– Faces Servlet –> <servlet> </servlet>
<servlet> </servlet>
<servlet> </servlet>
<!– extension mapping –> <servlet-mapping> </servlet-mapping>
<servlet-mapping> </servlet-mapping>
<servlet-mapping> </servlet-mapping>
<servlet-mapping> </servlet-mapping>
<servlet-mapping> </servlet-mapping>
<session-config> </session-config>
<!– Welcome files –> <welcome-file-list> </welcome-file-list>
</web-app> |
También
en
WEB-INF creamos el fichero faces-config.xml. Partimos del
código que se muestra
a continuación y lo iremos completando posteriormente.
<?xml version=‘1.0’ encoding=‘UTF-8’?>
<!DOCTYPE faces-config PUBLIC «-//Sun Microsystems, Inc.//DTD JavaServer «http://java.sun.com/dtd/web-facesconfig_1_1.dtd»>
<!– =========== FULL CONFIGURATION FILE
<faces-config xmlns=«http://java.sun.com/JSF/Configuration»> <application> <locale-config> </locale-config> </application>
</faces-config> |
Ahora entramos en
la capa vista de nuestra aplicación. Creamos un welcome
file, digamos,
WEB-INF/index.jsp que vaya a la página del web que nos
interese:
<html> <head> </head> <body> </body> </html> |
Creamos el fichero
apuntado: starcatalogue.jspx. Tendrá como contenido el
código HTML bien formado
junto con los componentes de JSF e ICEfaces.
Vamos a implementar
la primera funcionalidad de la web, el buscador predictivo de estrellas
del
catálogo. Queremos que cuando empecemos a escribir
texto, se muestren
automáticamente los resultados más cercanos.
Así, cuando el nombre de la
estrella buscada esté a nuestra vista podemos hacer click
con el ratón sobre su
nombre y mostrar la información del astro.
Consultamos el TAG
list de los componentes que ofrece ICEfaces (ver
documentación online o en la
distribución descargada en nuestro ordenador, e.g.
ICEfaces-1.6.2-bin/icefaces/docs/tld/index.html)
y encontramos las que mejor nos sirvan:
·
ice:outputText para mostrar texto al usuario.
·
Ice:form para crear el formulario.
·
ice:selectInputText para implementar un
cuadro de búsqueda
preditivo.
·
ice:graphicImage para mostrar una imagen
(e.g. banner, cabecera,
etc.).
·
ice:panelGroup para agrupar componentes.
·
ice:panelGrid para que el formulario y el
texto de los
componentes respectivos se muestren en la página ordenados
(en realidad
equivale al uso de capas o tablas en HTML tradicional para configurar
el layout
de la interfaz).
Hemos diseñado la
interfaz con este aspecto:
Por
lo que lo
implementamos en catalogue.jspx así:
<f:view xmlns:f=«http://java.sun.com/jsf/core» <html> <head> </head> <body> <p style=«width:800px;»> <ice:graphicImage url=«img/header.jpg» style=«border:none;»/> <br/><br/>
</body> </html> </f:view> |
Puede apreciarse en
el código que hemos introducido invocaciones a atributos de
javabeans. Nuestro
código implementará la lógica
necesaria para actualizarlos y para responder a
los eventos generados en clientes y atendidos en servidor. Es el caso
del
atributo valueChangeListener, que invoca el método listener
updateStarList de autoCompleteCatalogBean.
Los nombres de los beans son un mapeo con ficheros de código
reales, con igual
o distinto nombre.
Implementación de los beans
La lógica de la
aplicación la crearemos en la carpeta de fuentes del
proyeto, src bajo
paquetes:
·
com.autentia.starcatalogue: creamos las
clases StarBean.java que
modelará una entidad de tipo estrella, y SkyData.java con
datos que
necesitaremos.
package com.autentia.starcatalogue;
/** * * Simple Star entity definition for database information * * * @version 1.0 * */ public class StarBean
}
|
package com.autentia.starcatalogue;
import java.util.ArrayList; import java.util.List; import javax.faces.model.SelectItem;
/** * * Generic sky data * * * @version 1.0 * */ public class SkyDataBean {
} |
Las dependencias
para usar ICEfaces en nuestro proyecto, que debemos copiar en el lib
del
proyecto e integrar en el classpath de Eclipse son:
o
jsf-api.jar
o
jsf-impl.jar
o
servlet-api.jar
o
backport-util-concurrent.jar
o
commons-beanutils.jar
o
commons-collections.jar
o
commons-discovery.jar
o
commons-digester.jar
o
commons-fileupload.jar
o
commons-logging.jar
o
commons-logging-api.jar
o
el-api.jar
o
icefaces.jar
o
icefaces-comps.jar
o
xercesImpl.jar
o
xml-apis.jar
·
com.autentia.starcatalogue.search:
AutoCompleteCatalogDictionary.java.
Partiremos de uno de los ejemplos de la documentación de
ICEfaces
(autocompletado) y lo modificaremos. Esta clase cargará el
catálogo de
estrellas de disco y mantendrá disponible en el
ámbito de la aplicación.
También crearemos AutoCompleteCatalogBean.java que
responderá a eventos de la
interfaz.
/* * […] * The Original Code is ICEfaces 1.5 * November 5, 2006. The Initial * Technologies Canada, Corp. Portions * 2004-2006 ICEsoft Technologies * [..p] */
package com.autentia.starcatalogue.search;
import com.autentia.starcatalogue.StarBean; import
import javax.faces.event.ValueChangeEvent; import javax.faces.model.SelectItem; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List;
/** * Stores the values picked from the * avoid memory hole). * * CHANGELOG [02/01/2007]: modified * CHANGELOG [03/01/2007]: introduced * * @see AutoCompleteCatalogueDictionary * @author The Original Code is * @version 2.1 */ public class AutoCompleteCatalogBean {
} |
/* * […] * The Original Code is ICEfaces 1.5 * November 5, 2006. The Initial * Technologies Canada, Corp. Portions * 2004-2006 ICEsoft Technologies * [..p] */
package com.autentia.starcatalogue.search;
import com.autentia.starcatalogue.StarBean;
import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; import javax.servlet.http.HttpSession; import java.beans.XMLDecoder; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.ListIterator;
/** * * * * Application-scope bean used to * AutoComplete (selectInputText) * AutoCompleteCatalogBean as the * * CHANGELOG [02/01/2007]: modified * CHANGELOG [03/01/2007]: introduced * * @see AutoCompleteCatalogBean * @author The Original Code is * @version 2.4 */ public class AutoCompleteCatalogDictionary {
} |
Completamos el fichero faces-config
con los nuevos beans
definidos para que puedan ser resueltos desde la vista:
<?xml version=‘1.0’ encoding=‘UTF-8’?>
<!DOCTYPE faces-config PUBLIC «-//Sun Microsystems, Inc.//DTD JavaServer «http://java.sun.com/dtd/web-facesconfig_1_1.dtd»>
<!– =========== FULL CONFIGURATION FILE
<faces-config xmlns=«http://java.sun.com/JSF/Configuration»> <application> <locale-config> </locale-config> </application>
<!– Search engine <managed-bean> <managed-bean-name>autoCompleteCatalogDictionary</managed-bean-name> <managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>autoCompleteCatalogBean</managed-bean-name> <managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> </managed-property> </managed-bean> </faces-config> |
En el directorio
WEB-INF/resources/starcatalogue.xml se
almacenará la instancia persistente del catálogo
estelar. Lo crearemos con un
contenido inicial con propósitos de prueba:
<?xml version=«1.0» encoding=«UTF-8»?> <java version=«1.5.0_14» class=«java.beans.XMLDecoder»> <object class=«java.util.ArrayList»> <void method=«add»> <object class=«com.autentia.starcatalogue.StarBean»> <void property=«briefDescription»> <string>The 4th brightest star in the northern </void> <void property=«constellation»> <string>Bootes</string> </void> <void property=«magnitude»> <string>-0.1</string> </void> <void property=«name»> <string>Arcturus</string> </void> </object> </void> <void method=«add»> <object class=«com.autentia.starcatalogue.StarBean»> <void <string>Binary star with an orbital period og 470 years</string> </void> <void property=«constellation»> <string>Gemini</string> </void> <void property=«magnitude»> <string>1.9</string> </void> <void property=«name»> <string>Castor</string> </void> </object> </void> <void method=«add»> <object class=«com.autentia.starcatalogue.StarBean»> <void property=«briefDescription»> <string>Alpha Cygnus, 3000 light-years far away from </void> <void property=«constellation»> <string>Cygnus</string> </void> <void property=«magnitude»> <string>1.3</string> </void> <void property=«name»> <string>Deneb</string> </void> </object> </void> </object> </java> |
Vamos a ver los primeros resultados.
Creamos un script ant a
nivel raiz de proyecto : build.xml.
<project name=«starcatalogue» default=«build.war»>
<property name=«build.sysclasspath» value=«ignore»/>
<property name=«build.dir» location=«build»/> <property name=«dist.dir» location=«dist»/> <property name=«src.dir» location=«src»/> <property name=«web.content.dir» location=«web»/> <property name=«web.inf.dir» location=«${web.content.dir}/WEB-INF»/> <property name=«classes.dir» location=«${web.inf.dir}/classes»/> <property name=«app.lib.dir» location=«${web.inf.dir}/lib»/> <property name=«autentiaApp.lib.dir» location=«lib»/> <property name=«compile.source» value=«1.4»/> <property name=«compile.target» value=«1.4»/> <property name=«compile.debug» value=«true»/>
<macrodef name=«clean»> <sequential> </sequential> </macrodef>
<macrodef name=«compile»> <attribute name=«src.copy.excludes» default=«»/> <element name=«add.javac.elements» optional=«true»/>
<sequential>
</sequential> </macrodef>
<macrodef name=«build.war»> <attribute name=«war.file.name» default=«${ant.project.name}.war»/> <element name=«add.filesets» optional=«true»/>
<sequential>
</sequential> </macrodef>
<target name=«clean»> <clean/> </target>
<target name=«compile»> <compile/> </target>
<target name=«build.war» depends=«compile»> <build.war/> </target>
</project> |
En este punto, la
situación actual del proyecto en eclipse
es la siguiente:
Desde consola y en el directorio del
proyecto ejecutamos ant
build.war, copiamos el starcatalogue.war (generado en dist) en la
carpeta
webapps del Tomcat y levantamos el servidor. Accedemos a la
aplicación (e.g. http://localhost:8080/starcatalogue)
y veremos algo como lo siguiente:
Ampliando el catálogo
Vamos a añadir la segunda
funcionalidad a nuestra web: la de
poder añadir estrellas a nuestro
catálogo. Para una nueva estrella debemos
introducir (de manera obligatoria, si no no se efectúa la
acción) su nombre, el
de la constelación que la alberga, la magnitud de su brillo
y una breve
descripción.
Vamos a hacer una
clasificación de las constelaciones: si
son circumpolares, zodiacales, o de otra zona. En función de
la zona
seleccionada en un combo, la lista de constelaciones seleccionables en
un
segundo combo son diferentes.
Finalmente confirmamos la
operación con un mensaje de texo.
Usaremos el componente
ice:selectOneListBox para mostrar un
HTML select junto con el atributo partialSubmit. Esto es importante
para hacer
uso de Ajax: cuando se modifica este combo, se realiza una request
inmediata al
servidor invocando al listener definido en el atributo
valueChangeListener;
este listener filtrará las constelaciones de esa zona.
A starcatalogue.jspx
añadimos, antes del </body>:
<!– Star insertion form |
Creamos el listener
ContributionBean.java bajo un paquete
com.autentia.starcatalogue.contribution:
package com.autentia.starcatalogue.contribution;
import java.util.ArrayList; import java.util.List;
import javax.faces.event.ActionEvent; import javax.faces.event.ValueChangeEvent; import javax.faces.model.SelectItem;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import com.autentia.starcatalogue.SkyDataBean; import com.autentia.starcatalogue.StarBean; import import
/** * * Controller for the contribution functionality of the site * * * @version 1.0 */ public class ContributionBean extends SkyDataBean {
} |
A la clase
AutoCompleteCatalogBean.java le añadimos los
métodos:
/**
|
Finalmente completamos el descriptor
faces-config.xml:
<!– Adding stars to the catalogue – <managed-bean> <managed-bean-name>contributionBean</managed-bean-name> <managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>skyData</managed-bean-name> <managed-bean-class> </managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean> |
De nuevo construimos el war,
desplegamos en Tomcat, y
accedemos a la web. Obtendremos ahora:
Ya tenemos nuestra primera web con
ICEfaces completa.
Dependiendo de tus conocimientos previos habrás dedicado
más o menos tiempo a
realizarlo; pero lo importante es asomarse a la nueva
tecnología y sacar tus
propias conclusiones de cómo ello puede favorecerte en tus
desarrollos.
En AUTENTIA compartimos nuestro
conocimiento en últimas
tecnologías, sobre las que profundizamos para aplicarlas en
nuestro trabajo.
Siempre puedes contactarnos en www.autentia.com
para impartir cursos especializados, dar soporte, o aplicarlo
directamente a los
proyectos de tu empresa.
Hola Iván,
En una segunda pasada del tutorial, y con ánimo de crítica constructiva, creo que sería bueno que fueras más esquemático a la hora de desarrollar el tutorial. Existe demasiado código fuente y pantallazos y poca redacción. Desde mi punto de vista, te ánimo a que redactes más, explicando que vas realizando en cada paso.
Enhorabuena y gracias por la aportación.
Hola Jaime,
gracias por visitar de nuevo el tutorial y por tu crítica. Seguro que aportas esta idea porque ahora dominas más IceFaces y ves que este tutorial podría explicarse mejor. Y es cierto 😉 También fue mi primera aplicación autodidacta con IceFaces y mi primer tutorial (y andaba algo perdido todo sea dicho) a si que ambas cosas son muy mejorables, pero por algo se empieza…
Saludos y gracias a tí
Buenas Iván
E realizado meticulosamente el tutorial y no tengo proble mas hasta que ejecuto ant build.war hay me aparece lo siguiente:
mario@mario-desktop:~/workspace/TutorialIcefaces$ ant buil.war
Buildfile: build.xml
BUILD FAILED
Target \\\»buil.war\\\» does not exist in the project \\\»starcatalogue\\\».
Total time: 0 seconds
Tendrias idea con tu experiencia cual seria el problema, lo e intentado desde el ide y tampoco e podido.
De antemano gracias por tu tiempo.-
Mario, el target del ant es sobre build.war, y el la linea de comandos aparece \\\»ant buil.war\\\», comprueba la sintaxis.
Gracias por responder tan rapido la salida es asi
mario@mario-desktop:~/workspace/TutorialIcefaces$ ant buil.war
Buildfile: build.xml
BUILD FAILED
Target \\\»buil.war\\\» does not exist in the project \\\»starcatalogue\\\».
La verdad que estoy desorientado.
Las barras \\\»\\\\\\\\\\\\\\\» no se porque se agregan cuando pego la pantalla
Mario, el comando que debes ejecutar es ant build.war (en tu comentario se ve que no está bien escrito, falta una \\\’d\\\’).
Si perdon la pantalla es esto es lo que me aparece ahora desde la consola y desde el ide anterior mente.
…
[javac] 26 errors
BUILD FAILED
/home/mario/workspace/TutorialIcefaces/build.xml:179: The following error occurred while executing this line:
/home/mario/workspace/TutorialIcefaces/build.xml:91: Compile failed; see the compiler error output for details.
Total time: 4 seconds
Gracias Iván por contestar a comentarios, se ve que eres una persona paciente y con vocación didáctica. En una tercera pasada, he vuelto a aprender conceptos nuevos, aportados en este tutorial 😉
Saludos!
\\\»A la clase AutoCompleteCatalogBean.java le añadimos los métodos:\\\» en esta parte hay un error, me parece que debe agregarse a la clase AutoCompleteCatalogDictionary, soy novato en esto del icefaces gracias por compartir el conocimiento
La verdad no entiendo muy bn este tutorial, tengo problemas con este componente ya que necesito el autocompletar con unos datos de una BD oracle, he leeido directamente desde la pagina de icefaces y no es muy diferente….si me pudieras ayudar a aclarar como hacer para llenar el autocomplete desde la BD te agradeceria.
que no nos puedes pasar el war