Posted on 12-09-2007
Filed Under (Java, Programaci贸n) by galifate

Aqu铆 tenemos un art铆culo de ejemplo de uso, en una aplicaci贸n web, de las tecnolog铆as JSF, Spring 2.0 y Java Persistence. A continuaci贸n, a modo de pr谩ctica de ingl茅s t茅cnico y para no desconectarme demasiado de las tecnolog铆as web java, puesto que cada vez programo menos, os pongo una traducci贸n y tal. El articulo est谩 sacado del blog de Carol McDonald, dentro de Java.net.

A modo de mostrar el uso de JSF, Spring 2.0 y Java Persistence en Glassfish, la autora ha montado una aplicaci贸n de ejemplo que consiste en paginaci贸n de conjuntos de datos sobre un cat谩logo de una tienda.

Paginaci贸n de Conjuntos de Datos en una Aplicaci贸n de Ejemplo usando las APIs de JSF, Spring 2.0 y Java Persistence en Glassfish

Esta aplicaci贸n de ejemplo de un cat谩logo de una tienda demuestra el uso de JavaServer Faces, la nueva API de Java Persistence, y Spring 2.0 para implementar la paginaci贸n. La autora cogi贸 el ejemplo Pagination of Data Sets in a Sample Application using JSF, Catalog Facade Stateless Session, and Java Persistence APIs y lo modific贸 ligeramente para usar Spring Bean en lugar de los beans de sesion sin estado de EJB 3.0. Si se comparan los dos ejemplos, ver谩s que el c贸digo es casi el mismo, la principal diferencia es la configuraci贸n en xml extra para Spring, lo cual no es f谩cil.

Descarga el c贸digo de la aplicaci贸n de ejemplo SpringJPA

N贸tese: la autora modific贸 la parte de integraci贸n de Spring JSF en esta aplicaci贸n para usar org.springframework.web.jsf.DelegatingVariableResolver en lugar del Managed Bean ServiceLocator para obtener una referencia al CatalogService Spring Bean desde el application context de Spring.

Explicaci贸n del uso de JSF, Spring 2.0, y Java Persistence API en un aplicaci贸n de ejemplo del cat谩logo de una tienda

La siguiente imagen muestra la p谩gina de la Lista del Cat谩logo, que permite a un usuario ojear la lista de productos de una tienda.

listpage.jpg

La p谩gina List.jsp usa un componente JSF dataTable para mostrar una lista de productos del cat谩logo.

El componente dataTable es 煤til cuando quieres mostrar un conjunto de resultados en una tabla. En una aplicaci贸n de JavaServer Faces, el componente UIData (la superclase de dataTable) soporta el binding a una colecci贸n de objetos de datos. Hace el trabajo de iteraci贸n sobre cada registro de la fuente de datos. El dataTable renderer de HTML muestra los datos como una tabla HTML.

En la p谩gina web List.jsp la dataTable est谩 definida como se muestra a continuaci贸n: (Nota: el color Rojo son para los tags Java EE, anotaciones de c贸digo, Azul para Spring y Verde para el c贸digo de la autora o variables)

C贸digo de Ejemplo: List.jsp

<h:dataTablevalue=’#{item.items}var=’dataTableItem‘ border=”1″
cellpadding=”2″ cellspacing=”0″>

El atributo value de un tag dataTable se refiere a los datos a ser inclu铆dos en la tabla.

El atributo var especifica un nombre que lo usan los componentes que est谩n dentro del tag dataTable com un alias de los datos referenciados por el atributo value. En el tag dataTable de List.jsp, el atributo value apunta a una lista de productos del cat谩logo. El atributo var apunta a un s贸lo elemento de esa lista. Como el componente UIData itera por la lista, cada referencia a dataTableItem apunta al elemento actual en la lista.

El value de dataTable est谩 limitado a la propiedad items de la clase controlador de item, ItemController, que est谩 definido en el fichero faces-config.xml:

C贸digo de: faces-context.xml

<managed-bean>
<managed-bean-name>item</managed-bean-name>
<managed-bean-class>
sessionpagination.ItemController
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>catalogService</property-name>
<value>#{catalogService}</value>
</managed-property>

</managed-bean>


La propiedad items se define como se muestra a a continuaci贸n:

C贸digo de: ItemController.java
public DataModel getItems() {
if (model==null || index != firstItem){
model=getNextItems();
}
return this.model;
}public DataModel getNextItems() {
model = new ListDataModel(catalogService.getItems(firstItem,batchSize));
index = firstItem;
return this.model;
}

El m茅todo getItems() recubre una List de objetos item, devuelto desde el catalogService, en un DataModel.

UIData, la superclase de dataTable, soporta data binding a una collection de objetos de datos representado por una instancia de DataModel. La collection de datos subyacente a una instancia de DataModel se modelo como una colecci贸n de objetos fila que pueden ser accedidos por un 铆ndice de fila. La API da mecanismos para posicionarse en un 铆ndice de fila especificado, y para devolver una objeto que represente los datos que corresponden a la fila actual.

Las propiedades de Item Name, Photo, y price se muestran con el componente column:

Ejemplo de c贸digo de: List.jsp

<h:column>
<f:facet name=”header“>
<h:outputText value=”Price”/>
</f:facet>
<h:outputText value=”#{dataTableItem.price}”/>
</h:column>

Los tags column representan columnas de datos en un componente UIData. Mientras este componente itera por las filas de datos, procesa el componente UIColumn asociado con cada tag column por cada fila de la tabla.

El componente UIData itera por la lista de elementos (item.items) y muestra el dataTableItem.price. Cada vez que UIData itera por la lista de items, pinta una celda en cada column.

Los tags dataTable y column usan facet para representar partes de la tabla que no son repetidas o modificadas. Estas partes incluyen las cabeceras, los pie y los t铆tulos.

El modo recomendado para integrar Spring con JSF es configurar el DelegatingVariableResolver de Spring en el faces-context.xml. Los elementos <application> <variable-resolver> de un fichero faces-config.xml permiten a una aplicaci贸n basada en Faces registrar clases personalizadas para sustituir la implementaci贸n est谩ndar de VariableResolver. El DelegatingVariableResolver de Spring primero delega al resolver original de la implementaci贸n subyacente de JSF, para luego delegar al WbApplicationContext ra铆z de Spring.Esto permite configurar los Spring Beans como propiedades gestionadas por los Managed Beans de JSF. Por ejemplo, el catalogService Spring Bean est谩 configurado como una managed property del ItemController JSF ManagedBean:

Ejemplo de c贸digo de: faces-context.xml
<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
<managed-bean>
<managed-bean-name>item</managed-bean-name>
<managed-bean-class>
sessionpagination.ItemController
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>catalogService</property-name>
<value>#{catalogService}</value>
</managed-property>

</managed-bean>

El catalogService, y su implementaci贸n CatalogDAO, se define como un Spring bean en el fichero de configuraci贸n /WEB-INF/applicationContext.xml :

Ejemplo de c贸digo de: applicationContext.xml

<bean id=”catalogServiceclass=”service.CatalogDAO“/>

<bean name=”itemControllerclass=”sessionpagination.ItemController“>
<property name=”catalogService“>
<ref bean=”catalogService“/>
</property>
</bean>

</beans>

<property name=”catalogService“> se refiere al m茅todo setCatalogService de ItemController. El WebApplicationContext de Spring“inyecta” el Spring Bean catalogService dentro de la property catalogService del ItemController JSF ManagedBean :

Ejemplo de c贸digo de: ItemController.java

public class ItemController {
private CatalogService catalogService ;public void setCatalogService(CatalogService catalogService) {
this.catalogService = catalogService;
}

Para m谩s informaci贸n sobre el uso de JSF con Spring, ver Spring - Java/J2EE Application Framework Integrating with JavaServer Faces .

Usando la Java Persitence API (JPA) con Spring 2.0

El Spring bean CatalogDAO usa el objeto EntityManager Query de la Java Persistence API para devolver una lista de items. El CatalogDAO anota el campo private EntityManager em; con @PersistenceContext , que hace que un entity manager sea inyectado. (n贸tese que usar la anotaci贸n @PersistenceContext es el mismo m茅todo para inyectar un Entity Manager para un EJB 3.0 Session Bean.)

Ejemplo de c贸digo de: CatalogDAO.java

@Repository
@Transactional
public class CatalogDAO implements CatalogService {
@PersistenceContext(unitName=”PetCatalogPu”)
private EntityManager em;public List<Item> getItems(int firstItem,int batchSize) {
Query q = em.createQuery(”select object(o) from Item as o”);
q.setMaxResults(batchSize);
q.setFirstResult(firstItem);
List<Item> items= q.getResultList();
return items;
}

La Java Persistence Query APIs se usa para crear y ejecutar consultas que puedan devolver una lista de resultados. La interfaz JPA Query suministra soporte para paginaci贸n v铆a los m茅todos setFirstResult() y setMaxResults(): q.setMaxResults(int maxResult) establece el n煤mero m谩ximo de resultados a devolver. q.setFirstResult(int startPosition) establece la posici贸n del primer resultado a devolver.

En el siguiente c贸digo, se muestra la clase de entidad de Item que se “mapea” con la tabla ITEM que guarda las instancias de item. 脡ste es un objeto de entidad t铆pico de la Java Persistence. Hay dos requisitos para una entidad:

  1. anotar la clase con la anotaci贸n @Entity.
  2. anotar el identificador de la clave primaria con @Id

Puesto que los campos name, description… son mapeos b谩sicos de los campos del objeto a las columnas del mismo nombre en la tabla de la base de datos, no necesitan ser anotados. Las relaciones O/R con Address y Product tambi茅n son anotadas. Para m谩s informaci贸n sobre definir entidades JPA ver Pro EJB 3: Java Persistence API book.

Ejemplo de c贸digo de: Item.java

@Entity
public class Item implements java.io.Serializable {
@Id
private String itemID;

private String name;
private String description;
private String imageurl;
private String imagethumburl;
private BigDecimal price;
@OneToOne(cascade={CascadeType.PERSIST})
private Address address;
@ManyToOne
private Product product;


public Item() { }
public String getItemID() {
return itemID;
}

public void setItemID(String itemID) {
this.itemID = itemID;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public void setAddress(Address address) {
this.address = address;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}

}

El ManagedBean ItemController pagina por la lista de items manteniendo los atributos firstItem y batchSize y pas谩ndolos como par谩metros al m茅todo CatalogService getItems(firstItem, batchSize). El <managed-bean-scope> de ItemController est谩 definido como session, un ManagedBean de JSF con un alcance de session significa que que las propiedades del bean estar谩n disponibles durante toda la vida de la sesi贸n HTTP.

La propiedad ItemController ItemCount se usa para obtener y mostrar el n煤mero de items del Cat谩logo de la base de datos en la p谩gina List.jsp:

Ejemplo de c贸digo de: List.jsp

<h:outputText value=”Item #{item.firstItem + 1}..#{item.lastItem} of
#{item.itemCount}”/>

Esta propiedad ItemController ItemCount se define como se muestra a continuaci贸n:

Ejemplo de c贸digo de: ItemController.java

public int getItemCount() {
int count = catalogService.getItemsCount();
return count;
}

El m茅todo ItemController getItemCount() llama a la interficie CatalogService para obtener el n煤mero de elementos de la lista. El m茅tod getItemCount() del bean de Spring CatalogDAO usa la Query interface de JPA para obtener el numero de elementos de la tabla items de la base de datos:

Ejemplo de c贸digo de: CatalogDAO.java
public class CatalogDAO implements CatalogService {
. . .
public int getItemCount() {
Query q = entityManager.createQuery(”select count(o) from Item as o”);
int count = ((Long)q.getSingleResult()).intValue();
return count;
}

Un commandLink de JSF se usa para dar un enlace en el que clicar para mostrar la siguiente p谩gina de items. El tag commandLink representa un hyperlink HTML y se renderiza como un elementos HTML <a>. El tag commandLink se usa para enviar un action event a la aplicaci贸n.

Ejemplo de c贸digo de: List.jsp

<h:commandLink action=”#{item.next}” value=”Next #{item.batchSize}”
rendered=”#{item.lastItem + item.batchSize <= item.itemCount}”/>

El atributo action de commandLink referencia al m茅todo next() del bean que hay detr谩s de ItemController, el cual calcula la primera fila de la siguiente p谩gina y devuelve un String que hace que List.jsp muestre la siguiente p谩gina de la lista. El m茅todo ItemController next se define como se muestrab a continuaci贸n:

Ejemplo de c贸digo de: ItemController.java
public String next() {
if (firstItem + batchSize < getItemCount()) {
firstItem += batchSize;
}
return “item_list“;
}

El NavigationHandler de JSF empareja el resultado l贸gico item_list con las reglas de navegaci贸n en el fichero de configuraci贸n de la aplicaci贸n faces-config.xml para determinar a qu茅 p谩gina acceder a continuaci贸n. En este caso, la implementaci贸n JSF carga la p谩gina List.jsp despu茅s del resultado de este m茅todo.

Ejemplo de c贸digo de: faces-config.xml
<navigation-rule>
<navigation-case>
<from-outcome>
item_list</from-outcome>
<to-view-id>/item/List.jsp</to-view-id>
</navigation-case>
</navigation-rule>

Se usa el commandLink de JSF para obtener un enlace para navegar a la p谩gina naterior. El atributo action se refiere al m茅todo ItemController prev() que calcula la primera fila de la p谩gina anterior y devuelve una salida l贸gica, que causa mostrar la p谩gina anterior de la lista de items:

Ejemplo de c贸digo de: List.jsp

<h:commandLink action=”#{item.prev}” value=”Previous #{item.batchSize}”
rendered=”#{item.firstItem >=item.batchSize}”/>

Este m茅todo ItemController prev() se define como se muestra a continuaci贸n:

Ejemplo de c贸digo de: ItemController.java
public String prev() {
firstItem -= batchSize;
if (firstItem < 0) {
firstItem = 0;
}
return “
item_list";
}

Se usa un ommandLink de JSF para obtener un enlace que clickar para mostrar una p谩gina con los detalles del item. El atributo action de commanLink referencia al m茅todo ItemController detailSetup():

Ejemplo de c贸digo de: List.jsp

<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:commandLink action=”#{item.detailSetup}” value=”#{dataTableItem.name}”/>
</h:column>

El m茅todo ItemController detailSetup() obtiene los datos de item de la fila actual del dataModel, y devuelve un string que hace que la p谩gina Detail.jsp muestre los detalles del item:

Ejemplo de c贸digo de: ItemController.java

public String detailSetup() {
item = (Item) model.getRowData();
return “item_detail“;
}

El NavigationHandler de JSF busca una coincidencia con el resultado obtenido, item_detail, para encontrar una regla de navegaci贸n en el fichero de configuraci贸n de la aplicaci贸n, y as铆 determinar a qu茅 p谩gina nos dirigiremos a continuaci贸n. en este caso, la implementaci贸n de JavaServer Faces carga la p谩gina Detail.jsp cuando finaliza este m茅todo.

Ejemplo de c贸digo de: faces-config.xml

<navigation-rule>
<navigation-case>
<from-outcome>item_detail</from-outcome>
<to-view-id>/item/Detail.jsp</to-view-id>
</navigation-case>
</navigation-rule>

La Detail.jsp usa el componente outputText para mostrar por pantalla las propiedades de item:

Ejemplo de c贸digo de: detail.jsp

<h:outputText value=”#{item.item.name}” title=”Name” />
<h:outputText value=”#{item.item.description}” title=”Description”/>
<h:graphicImage url=”#{item.item.imageurl}” title=”Imageurl” />
<h:outputText value=”#{item.item.price}” title=”Price” />
<h:outputText value=”#{item.item.address.city}” title=”Address” />
<h:outputText value=”#{item.item.contactinfo.email}” title=”Address”/>

detailpage.jpg

Conclusi贸n

Esto concluye la aplicaci贸n de ejemplo que demuestra como trabajar con dataTable y DataModel de JSF para paginar una lista de entidades Item obtenidas usando los m茅todos de Catalog que a su vez usa Java Persistence APIs con Spring 2.0.

Configurar las tablas de la base de datos para la aplicaci贸n de ejemplo:

  • editar las propiedades del fichero SpringJPA\setup\javadb.properties file, ejecutar el script ant del directorio SpringJPA\setup, o simplemente ejecutar el sql del directorio SpringJPA\setup\sql\javadb con cualquier herramienta para ello.

Configuraci贸n de la Aplication para Spring 2.0, JSF, JPA, ejecutandose en Glassfish

Para configurar glassfish y el proyecto Netbeans para Spring, la autora ha modificado los pasos descritos en Spring and Hibernate in GlassFish: Setting Things Up:

  • descargar y extraer Spring ( aqu铆 se ha usado la versi贸n 2.1).
  • Descargar e instalar NetBeans 5.5.1
  • Descargar e instalar GlassFish V1, siguiendo las instrucciones de la p谩gina de descarga. Tambi茅n puedes usar la distribuci贸n GlassFish de Sun, la Sun Java System Application Server PE 9.
  • A帽adir el servidor Glassfish a Netbeans:
  • Iniciar NetBeans e ir a la ventana Runtime (Ctrl+5).
  • Click derecho al nodo de Servers y seleccionar Add Server.
  • seleccionar Sun Java System Application Server (distribuci贸n binaria de GlassFish de Sun).
  • Navegar al sitio donde hayas instalado GlassFish y seleccionar Finish.

Crear la librer铆a de Spring en Netbeans:

  • Abrir la Netbeans Library Manager (men煤 Tools) y crea una nueva libreria que se llame Spring.
  • A帽ade los siguientes jars al Classpath:
  • dist/spring.jar, dist/weaving/spring-aspects.jar, lib/jakarta-commons/commons-logging.jar, lib/log4j/log4j-1.2.9.jar .
  • Establece el Sources con el directorio src de Spring.
  • Pon en Javadoc el directorio docs\api de Spring.
    Ahora esta librer铆a est谩 disponible para ser usada por cualquier proyecto.

Abrir y ejecutar el proyecto SpringJPA

Descargar la aplicaci贸n SpringJPA. Descomprime el c贸digo. Desde Netbeans haz “Open Project” y selecciona el proyecto de Netbeans SpringJPA del directorio que has descomprimido. La aplicaci贸n SpringJPA es un proyecto de Enterprise Application de Netbeans, que en realidad est谩 compuesto por dos proyectos: SpringJPa y SpringJPA-war. SpringJPA-war es un m贸dulo Java EE del proyecto SpringJPA. SpringJPA-war genera el fichero war y SpringJPA genera el fichero ear que contiene el war.

Abre el proyecto SpringJPA. Ver谩s el siguiente di谩logo cuando abras el proyecto, porque el proyecto de Aplicaci贸n de Empresa guarda la localizaci贸n absoluta a sus m贸dulos J2EE. Es necesario configurar la localizaci贸n de SpringJPA-war.

reference_problems

  • Haz click en Close. El proyecto SpringJPA estr谩 en rojo negrita.
  • Click derecho en el proyecto y selecciona Resolve Reference Problems del men煤 contextual.
  • Usa el di谩logo del Resolve Reference Problems para mapear el m贸dulo war de SpringJPA a su proyecto, que encontrar谩s en un subdirectorio dentro del directorio SpringJPA.
  • Despu茅s de resolver las referencias, click derecho en el proyecto SpringJPA y selecciona Open Required Projects (ahora que las dependencias est谩n correctas, el proyectto del war SpringJPA-war se abrir谩 siempre con el proyecto SpringJPA).
  • Aun hay problemas de referencias con el m贸dulo web, puesto que 茅ste referencia los ficheros jar de Spring necesarios para construir el proyecto.
  • A帽adir una nueva libreria de Spring al SpringJPA-war…
    en la ventana de proyecto bajo SpringJPA-war:
    click derecho en Librairies, Add Library
    Selecciona la Spring Library (que ya creamos antes) de la lista, y clicka en Add Library. As铆 a帽adir谩s los jars de Spring a tu proyecto SpringJPA-war.
  • Todas las referencia deber铆an estar ya resueltas. Haz click derecho sobre el proyecto SpringJPA y selecciona “clean and build project”.
  • Presiona F6 para testear el proyecto. Netbeans construir谩, empaquetar谩, desplegar谩 y lanzar谩 la aplicaci贸n.

Creando tu propio proyecto Netbeans con Spring y Glassfish:

  • Si quieres crear tu propia aplicaci贸n, crea una nueva Netbeans Enterprise Application:
  • En Netbeans selecciona File New Project, entonces selecciona Enterprise ..Enterprise Application, en la ventana New Enterprise Application, en Server elige Sun Java System Applicaton server, Java EE 5 Version, y selecciona Create Web Application Module:

newentapp.jpg

  • cambia las propiedades del proyecto de Netbeans para a帽adir la nueva libreria Spring …
    en la ventana del proyecto bajo el war de tu aplicaci贸n:
    click derecho sobre Libraries, Add Library
    Selecciona Spring Library de la lista, haz click en Add Library .
  • Para generar las clases de entidad de las tablas de la base de datos: en la ventana del proyecto, click derecho sobre el war, seleccionar new File..Persistence Entity clases de la base de datos. Clicka en next, selecciona la fuente de datos, las tablas y crea tu unidad de persistencia. Para m谩s info sobre como hacer esto, prueba con Java EE 5, EJB 3.0, Java Persistence API (JPA)
  • Para la configuraci贸n de Spring a帽ade el applicationConfiguration.xml y modifica el web.xml y el faces-config.xml como se describe a continuaci贸n.

Configuraci贸n de los ficheros XML para Spring 2.0, JSF, y JPA, ejecutandose en Glassfish

  • A帽ade el fichero /WEB-INF/applicationContext.xml al directorio WEB-INF del war. Este fichero est谩 donde defines tus beans de servicios Spring, y los resources. M谩s abajo est谩 el applicationContext.xml para la aplicaci贸n de ejemplo. Para m谩s informaci贸n sobre c贸mo configurar el applicationContext.cml de Spring para JPA ver este art铆culo: Using the Java Persistence API (JPA) with Spring 2.0

Ejemplo de c贸digo de: applicationContext.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:aop=”http://www.springframework.org/schema/aop”
xmlns:tx=”http://www.springframework.org/schema/tx”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd”>

<bean id=”catalogService” class=”service.CatalogDAO“/>
<bean id=”entityManagerFactory” class=”org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean”>
<property name=”dataSource” ref=”dataSource”/>
<property name=”loadTimeWeaver”>

Discutir en el foro (0)

    Read More   

Comments

[…] el Blog del Galifate podemo ver un tutorial sobre la introducci贸n al uso de los frameworks java Spring 2.0, JSF y JPA. […]


marcelo on 2 Mayo, 2008 at 10:19 am #

Esta bueno el articulo y la traduccion no esta tan mal :)


Post a Comment
Name:
Email:
Website:
Comments: