You are on page 1of 56

// Deprecated

java.util.Date fecha = new Date();


System.out.println (fecha.getDay());
System.out.println
(fecha.getMonth());

Pero se dieron cuentas que lo de las fechas tenía mucha más


intríngulis que simples "setters" y "getters" y todo esto ha
sido declarado obsoleto.

Pero tampoco nos pongamos tan tristes. Que todavía


podemos instanciar un objeto Date, y por supuesto, mostrarlo
por pantalla.

java.util.Date fecha = new Date();


System.out.println (fecha);

Calendar c1 = Calendar.getInstance();
Calendar c2 = new GregorianCalendar();

Una vez que tenemos instanciada nuestra clase Calendar ya


podremos hacer uso de los "getters" y "setters" de antaño. Pero con
una modificación y es que existe un único método get que recibe por
parámetro el tipo de información a recuperar en formato número
entero. Si bien, no tenemos que sabernos la correspondencia de
valores de los números enteros, ya que la clase Calendar nos ofrece
un conjunto de clases estáticas para facilitarnos la ayuda.
Relativo a estas constantes tenemos:
○ Calendar.DATE, que representa el día del mes.
○ Calendar.MONTH, que representa el mes del año.
○ Calendar.YEAR, que representa el año.
Tenemos muchas otras más DAY_OF_WEEK_IN_MONTH,
DAY_OF_WEEK, WEEK_OF_YEAR,...
Al final, nuestro código Java quedará algo así:

dia = Integer.toString(c.get(Calendar.DATE));
mes = Integer.toString(c.get(Calendar.MONTH));
annio = Integer.toString(c.get(Calendar.YEAR));

import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSDF {
public static void main(String args[]) {
SimpleDateFormat[] sdfs = {
new SimpleDateFormat("dd-MM-yyyy h:mm a"),
new SimpleDateFormat("dd/MMM/yy HH:mm:ss"),
new SimpleDateFormat("EEEE dd 'de' MMMM 'de' yyyy h:mm:ss:SSS")
};
int numItera = 5;
for (Date d = new Date();;d = new Date(d.getTime()+1468800000))
{//3600000
for (SimpleDateFormat sdf : sdfs) {
System.out.println(sdf.format(d));
}
if (--numItera==0) break;
}
}
}
getMonth();
El Año:
getYear();
El dia:
getDay();
Hora:
getHours();
Minutos:
getMinutes();
Segundos:
getSeconds();

Ejemplo:

Date d=new Date();


System.out.println(Integer.toString(d.getHours()));
Aclaracion:
los valores que devuelven los metodos get indicados son de tipo integer:
para los dias
0=domingo
1=Lunes
...y asi sucesivamente
meses
0=enero
...
11=diciembre

otra cosa, al valor obtenido del año se debe sumar 1900.

Para obtener la fecha del sistema en un formato concreto se puede jugar con las clases Date
y SimpleDateFormat. Por un lado podemos sacar la fecha actual del sistema de la siguiente
forma:
Date fechaActual = new Date();
Ojo, estamos trabajando con el Date del paquete java.util no con el de java.sql

Una vez que lo tenemos se especifica el formato en que queremos la cadena


SimpleDateFormat formato = new SimpleDateFormat("yyyyMMdd");
y finalmente se obtiene la cadena
String cadenaFecha = formato.format(fechaActual);
Para el formato podemos jugar con las siguientes posibilidades
dd.MM.yy 09.04.98
yyyy.MM.dd G 'at' hh:mm:ss z 1998.04.09 AD at 06:15:55 PDT
EEE, MMM d, ''yy Thu, Apr 9, '98
h:mm a 6:15 PM
H:mm 18:15
H:mm:ss:SSS 18:15:55:624
K:mm a,z 6:15 PM,PDT
yyyy.MMMMM.dd GGG hh:mm aaa
girasaol lapicero naranja y con lapicero dorado fehca naciemeinto—

Java » Obtener la hora en Java


Enero 25, 2007 por Víctor Cuervo . 62590 visitas 57 Comentarios Imprimir
Para obtener la hora del sistema, Java nos proporciona la clase
Calendar. Mediante dicha clase podremos obtener de una forma
separada cada uno de los valores que componen una hora.
Entendiendo como hora los segundos, minutos y hora.
Lo primero que tendremos que hacer será instanciar la clase Java
Calendar. Para ello podemos hacerlo de dos formas. La primera
consiste en obtener una instancia directamente de Calendar:

Calendar calendario = Calendar.getInstance();

La otra es instanciar la clase GregorianCalendar. Lo cual se haría


mediante la siguiente línea de código:

Calendar calendario = new GregorianCalendar();

GregorianCalendar es el formato de calendario soportado por una gran


parte del mundo. El cual es una mezcla del calendario Juliano y
Gregoriano. Dicho calendario fue instituido el 15 de octubre de 1582.
Vamos, que en ambos casos vamos a trabajar con el mismo
calendario.
Lo siguiente será declarar las variables que van a almacenar la hora.
Como hemos dicho al principio, dicha hora irá dividida en tres partes.
Consecuentemente tendremos 3 variables:

int hora, minutos, segundos;

Ahora calcularemos su valor. En la clase Calendar existe un método


get(int valor). Dicho método recibe un entero, el cual refleja el valor del
calendario que queremos obtener: la hora, el día, los minutos,....
Como la idea es que no nos sepamos que entero está asociado a que
valor, la clase Calendar nos proporciona una serie de constantes que
nos ayudarán a encontrar dichos valores. Así tendremos las siguientes
asociaciones:
○ Calendar.HOUR_OF_DAY, es la hora del día en formato 24 horas
○ Calendar.HOUR, el la hora en formato 12 horas
○ Calendar.MINUTE, representa a los minutos
○ Calendar.SECOND, serán los segundos
Una vez que conocemos esto, solo nos queda aplicar dichos valores al
método get y asociarlos a las variables. Veamos el código:

hora =calendario.get(Calendar.HOUR_OF_DAY);
minutos = calendario.get(Calendar.MINUTE);
segundos = calendario.get(Calendar.SECOND);
<h:outputLabel for=”from” value=”From:” />
<h:inputText id=”from” value=”#{scheduleBean.event.startDate}” />
<f:convertDateTime pattern=”dd/MM/yyyy” />
</p:inputMask>

h:form prependId=”false”>
<p:panel id=”panel” header=”New Person”>
<h:messages />
<h:outputText value=”5 characters minimum” />
<h:panelGrid columns=”3”>
<h:outputLabel for=”firstname” value=”Firstname: *” />
<h:inputText id=”firstname” value=”#{pprBean.firstname}” >
<f:validateLength minimum=”5” />
<p:ajax event=”blur” update=”panel” />
</h:inputText>
<h:message for=”firstname” />
</h:panelGrid>
</p:panel>
</h:form>

Continuando con el tutorial básico de aplicaciones Web con NetBeans, en esta sección veremos la aplicación
en ejecución y creare una pagina para mostrar los datos enviados del usuario.

Editamos el bean Login y reemplazamos la definición de la clase por


public class Login implements Serializable {
private static final long serialVersionUID = 1L;

y agregamos el import java.io.Serializable


Quedaría de la siguiente manera

Agregamos el metodo Validar()

public String Validar(){


return "usuario";
}
El valor de "usuario" corresponde al nombre de la pagina usuario.xhtml.

Editamos index.xhtml y agregamos en action="#{login.Validar}" a <h:commandButton


<h:commandButton value="Entrar" action="#{login.Validar}"/>

Creamos una pagina nueva


en Web Pages seleccionar Nuevo->Java Server Faces y en tipos de archivos JSF Page

indicamos el nombre
Agregamos <h:outputText para mostrar el nombre del usuario que se logeo
<h:outputLabel value ="#{login.username}"/>

quedaría
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:outputLabel value ="#{login.username}"/>
</h:body>
</html>

Ahora Ejecutamos la aplicación}

y al darle clic en el botón Entrar nos lleva a la siguiente pagina y nos muestra el nombre del usuario que
ingresamos en la pagina anterior.

CONVERSION!!!!!!!!

<h:inputText id="laEdad" converter="#{Integer}" styleClass="CajasTexto" size="30"


maxlength="3"
value="#{gestionUsuariosBean.edad}" />

VALIDACIONES Y CONVERSIONES EN JSF

Introducción

En este tutorial veremos como JSF proporciona mecanismos para el formateo,


conversión y validación de los componentes; veremos como estos mecanismos
pueden ser extendidos de forma sencilla para adaptarlos a nuestras
necesidades. La primera parte del tutorial estará dedicada al formateo y
conversión y la segunda a la Validación.
Para entender en qué momento de la vida de una página JSF se producen las
conversiones y validaciones de los componentes del formulario, quizá nos sea
de ayuda el siguiente diagrama:

JSF proporciona dos mecanismos separados que nos ayuda a validar los valores
introducidos por los usuarios a la hora de submitir los formularios:

El primer mecanismo es el de conversión y está definido por el interfaz


javax.faces.convert.Converter y sus múltiples implementaciones. Las
conversiones aseguran que el tipo de un dato introducido en un formulario JSF
sea el correcto, es decir, que el dato tipo cadena del formulario corresponde
con el tipo JAVA esperado, y que está especificado en la propiedad
correspondiente del bean. Los Conversores (implementaciones de la interfaz
Converter) son los componentes que se encargan de hacer estas
transformaciones (cadena>Tipo JAVA y viceversa). JSF invoca a los Conversores
antes de efectuar las validaciones y por lo tanto antes de aplicar los valores
introducidos a las propiedades del bean. En el caso de que un dato tipo cadena
no se corresponda con el tipo JAVA apropiado, el Conversor correspondiente
lanzará un ConversionException y el componente se marcará como invalidado.

El segundo mecanismo es el de validación y está definido por la interfaz


javax.faces.validator.Validator y sus múltiples implementaciones. El proceso de
validación se asegura que el dato introducido en el correspondiente
componente es correcto según la lógica de la aplicación. El proceso de
validación ocurre antes de que el FrameWork asigne los valores introducidos
en el formulario a las propiedades del bean y justo después de que se hayan
aplicado las conversiones, en el caso de que haya. Las validaciones aseguran
que un dato introducido en un formulario JSF tenga un valor correcto.

Los mensajes que lanzan tanto los Conversores como lo Validadores en el caso
de excepción se pueden mostrar en el formulario correspondiente a través de
la etiqueta messages.

A continuación vamos a ver 4 casos prácticos:

Un ejemplo de conversión utilizando un conversor estándar de JSF.

Un ejemplo de conversión realizada por un conversor que creemos nosotros.

Un ejemplo de validación utilizando un validador estándar de JSF.

Un ejemplo de validación utilizando un validador creado por nosotros.

Herramientas utilizadas

Sistema operativo: Windows XP Professional.

Servidor Web: Apache Tomcat 5.5.9

Entorno de desarrollo: Eclipse 3.1.1 con ExadelStudio-3[1].0.5

Preparamos el entorno

Seguiremos los siguientes pasos:

Creamos un nuevo proyecto JSF en Eclipse, al que llamaremos


PruebaValidaciones. Indicaremos durante la creación que el entorno JSF es
MyFaces 1.1.0. La estructura de directorios que nos queda es la siguiente:
Creamos la página index.jsp en el directorio WebContent: redireccionará a la
página home.jsf

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">

<html>
<head>AUTENTIA- TUTORIAL CONVERSIONES-VALIDACIONES</head>
<body>

<jsp:forward page="home.jsf" />

</body>

</html>
Creamos la página home.jsp en el directorio WebContent: esta página tendrá
enlaces a los diferentes ejemplos que vamos a hacer:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>


<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>

<html>
<head>
<title>AUTENTIA-Tutorial de Conversiones y validaciones</title>

</head>

<body>

<f:view>

<h:panelGrid id="cabecera" columns="2" styleClass="cabecera" >

<t:graphicImage id="logo" url="img/demo_logo.gif" alt="AUTENTIA -


Soluciones Reales para su empresa"/>
<f:verbatim>
&nbsp;&nbsp;
</f:verbatim>
</h:panelGrid>
<br/>
<h:outputLink value="conversion_estandar.jsf"><f:verbatim>Conversión
estándar</f:verbatim></h:outputLink> <br/>
<h:outputLink value="conversion_nuestra.jsf" ><f:verbatim>Nuestra
conversión</f:verbatim></h:outputLink> <br/>
<br />
<h:outputLink value="validacion_estandar.jsf" ><f:verbatim>Validación
estándar</f:verbatim></h:outputLink> <br/>
<h:outputLink value="validacion_nuestra.jsf" ><f:verbatim>Nuestra
validación</f:verbatim></h:outputLink> <br/>
<br />

</f:view>

</body>

</html>

Y si probamos lo poco que hemos hecho:

Los ejemplos que vamos a hacer a partir de este momento partirán de esta
página.
Primer ejemplo: usando un conversor estándar

Antes de nada debemos tener en cuenta que los conversores estándar que
proporciona JSF se dividen en conversores a tipos numéricos
(NumberConverter) y conversores a tipos Fecha (DateTimeConverter)

Existen dos formas de indicar que el valor de un determinado componente de


nuestra página va a ser “convertido”:

Añadiendo el atributo converter=”#{identificador_conversor}” al componente.


Sólo los componentes del tipo UIInput (inputText, inputSecret, inputHidden) y
outputText aceptan esta propiedad. Un ejemplo sería el siguiente:

<h:inputText converter=”#{Double}”

value=”#{modifyInvoicePage.invoice.amount}”/>

JSF deja a nuestra disposición los siguientes conversores estándar:

TIPO DE CONVERSOR IDENTIFICADOR DEL CONVERSOR

BigDecimalConverter BigDecimal

BigIntegerConverter BigInteger

NumberConverter Number

IntegerConverter Integer

ShortConverter Short

ByteConverter Byte

CharacterConverter Character

FloatConverter Float

DoubleConverter Double

BooleanConverter Boolean

DateTimeConverter DateTime
Incluyendo <f:convertNumber [lista_atributos]/> o <f:convertDateTime
[lista_atributos]/> dentro de la invocación al componente, como por ejemplo:

<h:inputText value=”#{modifyInvoicePage.invoice.amount}”>

<f:convertNumber type=”currency”/>

</h:inputText>

O por ejemplo

<h:inputText id=”invoiceDate”

value=”#{modifyInvoicePage.invoice.invoiceDate}”>

<f:convertDateTime pattern=”M/d/yyyy”/>

</h:inputText>

Los atributos disponibles para tipos number son:

NOMBRE DEL ATRIBUTO TIPO

currencyCode String

currencySymbol String

groupingUsed boolean

integerOnly boolean

locale java.util.Locale

maxFractionDigits int

maxIntegerDigits Int

minFractionDigits Int

minIntegerDigits int
pattern String

type String

Y los disponibles para tipos DateTime:

NOMBRE DEL ATRIBUTO TIPO

dateStyle String

parseLocale String o Locale

pattern String

timeStyle String

timeZone String o TimeZone

type String

Vamos a crear por fin el bean

La clase se llama com.autentia.tutorialValidacion.GestionUsuariosBean.java,


cuelga del directorio JavaSource y de momento tiene la siguiente pinta:

package com.autentia.tutorialValidacion;
import java.math.BigDecimal;
import java.util.Date;
/**
* Bean para probar conversiones y validaciones en JSF
* @author AUTENTIA

*/

public class GestionUsuariosBean

/** Nombre del usuario */


private String nombre;
/** Edad del usuario */
private int edad;
/** Fecha de nacimiento */
private Date fechaNacimiento;
/** Sueldo */
private BigDecimal sueldo;
/**
* Constructor
*/
public GestionUsuariosBean(){}

public int getEdad() {

return edad;

public void setEdad(int edad) {

this.edad = edad;
}
public Date getFechaNacimiento() {
return fechaNacimiento;
}
public void setFechaNacimiento(Date fechaNacimiento) {
this.fechaNacimiento = fechaNacimiento;
}
public String getNombre() {
return nombre;

public void setNombre(String nombre) {

this.nombre = nombre;
}
public BigDecimal getSueldo() {
return sueldo;
}
public void setSueldo(BigDecimal sueldo) {
this.sueldo = sueldo;
}

Y lo registramos en el fichero descriptor de JSF (WEB-INF/validaciones-


config.xml)

<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC

"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"

"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>

<managed-bean>

<description>Bean para probar


conversiones/validaciones</description>

<managed-bean-name>gestionUsuariosBean</managed-bean-
name>

<managed-bean-class>

com.autentia.tutorialValidacion.GestionUsuariosBean

</managed-bean-class>

<managed-bean-scope>session</managed-bean-scope>

</managed-bean>
</faces-config>

Creamos la página

La llamamos conversion_estandar.jsp y cuelga de WebContent:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>

<html>

<head>

<title>AUTENTIA - TUTORIAL VALIDACIONES/CONVERSIONES</title>

<link rel="stylesheet" type="text/css" href="css/estilos.css">


</head>

<body>

<f:view>

<h:form id="idUsuarios" name="gestionUsuariosBean">

<h:messages id="messageList" styleClass="error" showSummary="true"


showDetail="true" />

<h:panelGrid columns="2" styleClass="gestionUsuariosFormTable"

headerClass="gestionUsuariosFormHeader"

footerClass="gestionUsuariosFormFooter"

columnClasses="gestionUsuariosFormLabels,
gestionUsuariosFormInputs" width="600">

<!-- Nombre -->


<h:outputLabel for="login" value="Nombre"/>
<h:panelGroup>

<h:inputText id="nombre" styleClass="CajasTexto" size="30"


maxlength="100"

value="#{gestionUsuariosBean.nombre}" />

</h:panelGroup>

<!-- Edad -->

<h:outputLabel for="edad" value="Edad"/>

<h:panelGroup>

<h:inputText id="laEdad" converter="#{Integer}"


styleClass="CajasTexto" size="30" maxlength="3"

value="#{gestionUsuariosBean.edad}" />

</h:panelGroup>

<!-- Fecha de nacimiento -->


<h:outputLabel for="fechaNacimiento" value="Fecha de nacimiento"/>
<h:panelGroup>

<h:inputText id="fecha" styleClass="CajasTexto" size="30"


maxlength="12"
value="#{gestionUsuariosBean.fechaNacimiento}">

<f:convertDateTime pattern="dd/MM/yyyy"/>

</h:inputText>

</h:panelGroup>

<!-- Sueldo -->

<h:outputLabel for="sueldo" value="Sueldo"/>

<h:panelGroup>

<h:inputText converter="#{BigDecimal}" styleClass="CajasTexto"


size="30" maxlength="15"

id="idSueldo"
value="#{gestionUsuariosBean.sueldo}" />

</h:panelGroup>

<h:panelGroup>

<h:commandButton action="resultado_conversion"
value="Validar" />

<f:verbatim>&nbsp;</f:verbatim>
</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>
</body>
</html>

Como vemos, es muy sencillo utilizar los conversores estándar y cualquier


explicación sobra. Para que el botón de Validar funcione, debemos añadir la
correspondiente regla de navegación en el fichero WEB-INF/validaciones-
config.xml:

..
<navigation-rule>

<from-view-id>/conversion_estandar.jsp</from-view-id>

<navigation-case>

<from-outcome>resultado_conversion</from-outcome>

<to-view-id>/resultado_conversion.jsp</to-view-id>

<redirect/>

</navigation-case>

</navigation-rule>


Y para que el ejemplo nos quede chulo, creamos la página que dice que dice
que todo ha ido bien y muestra los valores introducidos por el usuario:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>

<html>

<head>

<title>AUTENTIA - TUTORIAL
VALIDACIONES/CONVERSIONES</title>

<link rel="stylesheet" type="text/css" href="css/estilos.css">

</head>

<body>

<f:view>

<h:form id="idUsuarios" name="gestionUsuariosBean">

<h:messages id="messageList" styleClass="error" showSummary="true"


showDetail="true" />

<h:panelGrid columns="2" styleClass="gestionUsuariosFormTable"

headerClass="gestionUsuariosFormHeader"

footerClass="gestionUsuariosFormFooter"

columnClasses="gestionUsuariosFormLabels,
gestionUsuariosFormInputs" width="600">

<!-- Nombre -->


<h:outputLabel for="login" value="Nombre"/>:
<h:panelGroup>

<h:outputText value="#{gestionUsuariosBean.nombre}"/>

</h:panelGroup>

<!-- Edad -->

<h:outputLabel for="edad" value="Edad"/>

<h:panelGroup>

<h:outputText value="#{gestionUsuariosBean.edad}"/>

</h:panelGroup>
<!-- Fecha de nacimiento -->
<h:outputLabel for="fechaNacimiento" value="Fecha de nacimiento"/>
<h:panelGroup>

<h:outputText value="#{gestionUsuariosBean.fechaNacimiento}"/>

</h:panelGroup>

<!-- Sueldo -->

<h:outputLabel for="sueldo" value="Sueldo"/>

<h:panelGroup>

<h:outputText value="#{gestionUsuariosBean.sueldo}"/>

</h:panelGroup>

<h:panelGroup>

<h:commandButton action="home" value="Volver" />

<f:verbatim>&nbsp;</f:verbatim>
</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>
</body>
</html>

Por ultimo, para completar el ejemplo, añadimos la navegabilidad para el botón


de volver, que retornará a la página home.jsp:

..

<navigation-rule>

<from-view-id>/resultado_conversion.jsp</from-view-id>

<navigation-case>

<from-outcome>home</from-outcome>

<to-view-id>/home.jsp</to-view-id>

<redirect/>

</navigation-case>

</navigation-rule>


Probamos

Vamos a introducir todos los valores incorrectos y vemos cual es el resultado:


Y ahora con valores correctos (bueno, menos la edad y el sueldo, pero eso no
hay forma que lo conozcan los conversores de JSF ;-) ):

Segundo ejemplo: creando nuestro propio conversor

Para crear nuestro propio conversor, debemos seguir los siguientes pasos:

Crear una clase que implemente la interfaz javax.faces.convert.Converter.

Implementar el método getAsObject, que convierte el valor del componente


que tengamos en la página (tipo cadena) a un objeto (tipo JAVA que requiera la
aplicación).

Implementar el método getAsString, que convierte el objeto (tipo JAVA de


nuestra aplicación) a tipo cadena (requerido por la página).

Registrar el nuevo conversor en el contexto de JSF.

Utilizarlo en la página insertando dentro del componente cuyo valor queramos


convertir el tag <f:converter>.

Qué va hacer nuestro conversor

Va a desglosar un número de teléfono de tipo:


91-888 33 66

En dos partes:

Prefijo = 91

Número de teléfono= 888 33 66

El conversor lanzará excepciones si:

No se introduce el guión para separar el prefijo del número

Si el prefijo no consta de 2 números

Si el número no consta de 7 números. Los espacios entre los números se


ignorarán

Creamos el conversor

Como hemos indicado antes, debe implementar la interfaz Converter y los


métodos getAsObject y getAsString. Vamos a llamarlo TelefonoConverter. Para
este ejemplo he utilizado la librería commons-lang de Yakarta que nos la
podemos descargar desde la página
http://jakarta.apache.org/site/downloads/downloads_commons-lang.cgi. La he
incorporado al paquete lib y he actualizado el classpath de la aplicación.

El método getAsObject va a devolver la instancia de una nueva clase


Telefono.java que tiene la siguiente pinta:

package com.autentia.tutorialValidacion;
/**
* Clase que representa un teléfono
* @author AUTENTIA

*/

public class Telefono

/** El prefijo */
private String prefijo;
/** El número de teléfono */
private String numero;
/**

* Constructor

*/

public Telefono(){}

public String getNumero() {

return numero;

public void setNumero(String numero) {

this.numero = numero;

public String getPrefijo() {

return prefijo;

public void setPrefijo(String prefijo) {

this.prefijo = prefijo;
}
/**
* Devuelve el número de teléfono como un String
*/

public String toString()

StringBuffer elNumero = new StringBuffer();

elNumero.append(prefijo);

elNumero.append("-");

elNumero.append(numero);

return elNumero.toString();

}
}
Y por fin la clase TelefonoConverter:

package com.autentia.tutorialValidacion;

import javax.faces.application.FacesMessage;

import javax.faces.component.UIComponent;

import javax.faces.context.FacesContext;

import javax.faces.convert.Converter;

import javax.faces.convert.ConverterException;

import org.apache.commons.lang.StringUtils;

/**
* Conversor de números de teléfono
* @author AUTENTIA
*/

public class TelefonoConverter implements Converter


{
/**
* Devuelve la representación Telefono de JAVA a partir del valor de un
componente JSF
*/

public Object getAsObject(FacesContext context, UIComponent


component, String value)

throws ConverterException
{
Telefono telefono = null;
if(!StringUtils.isEmpty(value))

telefono = new Telefono();

String valores[] = StringUtils.split(value,"-");

if(valores.length!=2)
throw new ConverterException(new
FacesMessage("El número de teléfono debe tener el siguiente formato: 'pp-
nnn nn nn', donde pp es el prefijo y nnn nn nn es el número"));
if(valores[0].length()!=2)
throw new ConverterException(new
FacesMessage("El prefijo del número de teléfono debe tener de tipo NN"));
String elNumero = StringUtils.remove(valores[1],' ');

if(elNumero.length()!=7)

throw new ConverterException(new


FacesMessage("El número de teléfono debe ser de tipo NNN NN NN"));
telefono.setPrefijo(valores[0]);
telefono.setNumero(valores[1]);
}
return telefono;
}
/**
* Devuelve la representacion cadena de un teléfono
*/

public String getAsString(FacesContext context, UIComponent


component, Object value)

throws ConverterException

return value.toString();

Adaptamos el bean GestionUsuariosBean para probar nuestro conversor

Añadimos un nuevo atributo de tipo Telefono al bean:



/** Teléfono */
private Telefono telefono;
….
….
public Telefono getTelefono() {
return telefono;
}
public void setTelefono(Telefono telefono) {
this.telefono = telefono;
}
….
…..

Registramos el nuevo conversor en el contexto de JSF

Para ello editamos el fichero WEB-INF/validaciones-config.xml y ponemos lo


siguiente:

…………

<converter>
<converter-id>autentia.telefonoConverter</converter-id>
<converter-
class>com.autentia.tutorialValidacion.TelefonoConverter</converter-class>
</converter>

…………..

Creamos la página conversión_nuestra.jsp que cuelga de WebContent:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>

<html>

<head>

<title>AUTENTIA - TUTORIAL
VALIDACIONES/CONVERSIONES</title>

<link rel="stylesheet" type="text/css" href="css/estilos.css">

</head>
<body>

<f:view>

<h:form id="idUsuarios" name="gestionUsuariosBean">

<h:messages id="messageList" styleClass="error" showSummary="true"


showDetail="true" />

<h:panelGrid columns="2" styleClass="gestionUsuariosFormTable"

headerClass="gestionUsuariosFormHeader"

footerClass="gestionUsuariosFormFooter"

columnClasses="gestionUsuariosFormLabels,
gestionUsuariosFormInputs" width="600">

<!-- Nombre -->


<h:outputLabel for="login" value="Nombre"/>
<h:panelGroup>

<h:inputText id="nombre" styleClass="CajasTexto" size="30"


maxlength="100"

value="#{gestionUsuariosBean.nombre}" />

</h:panelGroup>

<!-- Numero telefono -->


<h:outputLabel for="telefono" value="Numero de telefono"/>
<h:panelGroup>

<h:inputText id="telefono" styleClass="CajasTexto" size="30"


maxlength="12"

value="#{gestionUsuariosBean.telefono}">
<f:converter converterId="autentia.telefonoConverter" />
</h:inputText>

</h:panelGroup>

<h:panelGroup>

<h:commandButton action="resultado_conversion_nuestra"
value="Validar" />

<f:verbatim>&nbsp;</f:verbatim>
</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>
</body>
</html>

Y también añadimos la navegabilidad necesaria para que, una vez convertido


el valor, la aplicación vaya a la página de resultados
(resultado_conversion_nuestra) y para que desde esta página de resultados
podamos volver a la página home (home)

………

<navigation-rule>

<from-view-id>/conversion_nuestra.jsp</from-view-id>

<navigation-case>

<from-outcome>resultado_conversion_nuestra</from-outcome>

<to-view-id>/resultado_conversion_nuestra.jsp</to-view-id>

<redirect/>

</navigation-case>

</navigation-rule>

<navigation-rule>

<from-view-id>/resultado_conversion_nuestra.jsp</from-view-id>

<navigation-case>

<from-outcome>home</from-outcome>

<to-view-id>/home.jsp</to-view-id>

<redirect/>

</navigation-case>
</navigation-rule>

………..

Y probamos:

Tercer ejemplo: utilizando validaciones estándar de JSF

En la primera parte de este tutorial hemos visto como los Conversores pueden
cubrir gran parte de la funcionalidad necesaria para validar que los valores
introducidos por los usuarios en un formulario JSF sean correctos.

En adición, los Validadores pueden realizar validaciones más genéricas


durantes la fase de Validación. Estos componentes implementan la interfaz
javax.faces.validator.Validator, que contiene un único método validate(). JSF
provee un conjunto de Validadores estándar que se describen en la tabla
siguiente:

CLASE DE TAG JSF ATRIBUTOS DESCRIPCIÓN


VALIDADOR

DoubleRangeValid validateDoubleRa minimum,maxim Valida que el


ator nge um valor del
componente sea
mayor que un
mínimo y mayor
que un máximo.
Este valor debe
ser tipo float

LengthValidator validateLength minimum,maxim Valida que la


um longitud del
valor del
componente
esté entre un
mínimo y un
máximo

LongRangeValidato validateLongRan minimum,maxim Valida que el


r ge um valor del
componente sea
mayor que un
mínimo y mayor
que un máximo.
Este valor debe
ser tipo entero

Además, myFaces proporciona los siguientes Validadores como adición a los


anteriores:

CLASE DE TAG JSF ATRIBUTOS DESCRIPCIÓN


VALIDADOR

EmailValidator validateEmail Valida que el


valor del
componente
tenga un formato
tipo email

CreditCardValidat validateCreditC none(true|false), Valida que el


or ard amex(true|false), valor del
visa(true|false), componente
mastercard(true| corresponde con
false), el número de los
discover(true|false) siguientes tipos
de tarjetas de
crédito:
American
Express,
Discover,
Mastercard, Visa.

RegExprValidator validateRegExp pattern Valida que el


r valor del
componente se
corresponde con
el patrón
especificado
como atributo

EqualValidator validateEqual for Valida que el


valor del
componente sea
exactamente
igual al valor del
componente
cuyo id se
corresponde con
el atributo for.

Preparamos el bean GestionUsuariosBean para el ejemplo

Vamos a efectuar las siguientes validaciones:

Que la edad del usuario esté comprendida entre 5 y 100 años

Que el nombre no tenga más de 40 caracteres

Que el nuevo atributo password debe ser igual que el campo repetición de
password

Por lo tanto, al bean sólo le falta un nuevo atributo password:

/** Password del usuario */


private String password;

public String getPassword() {

return password;

public void setPassword(String password) {

this.password = password;
}

Creamos la página

La llamaremos validación_estandar.jsp y colgará de WebContent:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>

<html>

<head>

<title>AUTENTIA - TUTORIAL
VALIDACIONES/CONVERSIONES</title>

<link rel="stylesheet" type="text/css" href="css/estilos.css">

</head>

<body>

<f:view>

<h:form id="idUsuarios" name="gestionUsuariosBean">

<h:messages id="messageList" styleClass="error" showSummary="true"


showDetail="true" />
<h:panelGrid columns="2" styleClass="gestionUsuariosFormTable"

headerClass="gestionUsuariosFormHeader"

footerClass="gestionUsuariosFormFooter"

columnClasses="gestionUsuariosFormLabels,
gestionUsuariosFormInputs" width="600">

<!-- Nombre -->


<h:outputLabel for="login" value="Nombre"/>
<h:panelGroup>

<h:inputText id="nombre" styleClass="CajasTexto" size="30"


maxlength="100"

value="#{gestionUsuariosBean.nombre}">

<f:validateLength maximum="50" />

</h:inputText>

</h:panelGroup>

<!-- Edad -->

<h:outputLabel for="edad" value="Edad"/>

<h:panelGroup>

<h:inputText id="laEdad" converter="#{Integer}"


styleClass="CajasTexto" size="30" maxlength="3"
value="#{gestionUsuariosBean.edad}">

<f:validateLongRange maximum="100" minimum="5"/>

</h:inputText>

</h:panelGroup>

<!-- Password -->

<h:outputLabel for="password" value="Password"/>

<h:panelGroup>

<h:inputSecret id="password" styleClass="CajasTexto" size="30"


maxlength="12" value="#{gestionUsuariosBean.password}" />

</h:panelGroup>
<!-- Repetición de password -->

<h:outputLabel for="password" value="Repetición de password"/>

<h:panelGroup>

<h:inputSecret id="passwordRepe" styleClass="CajasTexto" size="30"


maxlength="12" value="#{gestionUsuariosBean.password}">

<t:validateEqual for="password" />

</h:inputSecret>

</h:panelGroup>

<h:panelGroup>

<h:commandButton action="resultado_validacion"
value="Validar" />

<f:verbatim>&nbsp;</f:verbatim>
</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>
</body>
</html>

Añadimos la navegación en el fichero WEB-INF/validaciones-config.xml para


que el botón Validar vaya al sitio adecuado:

<navigation-rule>

<from-view-id>/validacion_estandar.jsp</from-view-id>

<navigation-case>

<from-outcome>resultado_validacion</from-outcome>

<to-view-id>/resultado_validacion.jsp</to-view-id>
<redirect/>

</navigation-case>

</navigation-rule>


El resultado

Cuarto ejemplo: creando nuestro propio Validador

Para crear nuestro propio Validador, debemos seguir los siguientes pasos:

Crear una clase que implemente la interfaz javax.faces.validator.Validator.

Implementar el método validate.

Registrar el nuevo validador en el contexto de JSF.

Utilizarlo en la página insertando dentro del componente cuyo valor queramos


validar el tag <f:validator>.

Qué va a validar nuestro Validador


Que el valor de un componente se corresponde un número de NIF válido.

El algoritmo que voy a utilizar para validar el NIF es el siguiente

Compruebo que el valor a validar tiene una longitud igual a 9. Los primeros 8
caracteres deben ser números (corresponden al DNI) y el último debe ser una
letra (la del NIF)

Almaceno la siguiente lista de letras en una variable:

“TRWAGMYFPDXBNJZSQVHLCKE”

Calculo el módulo entero de 23.

Recupero de la lista de letras la que se encuentra en la posición resultado de


efectuar el módulo entero de 23

Creamos el Validador

Como dijimos anteriormente, debe ser una implementación del interfaz


Validator:

package com.autentia.tutorialValidacion;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;

import javax.faces.component.UIComponent;

import javax.faces.context.FacesContext;

import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import org.apache.commons.lang.StringUtils;

/**
* Validador de NIF
* @author AUTENTIA
*/
public class NifValidator implements Validator

/**
* Efectúa el proceso de validación
*/
public void validate(FacesContext context,

UIComponent component, Object value) throws


ValidatorException

{
// Si el valor es null, lo transformamos en un valor vacío
String valor = StringUtils.defaultString((String)value);

// el valor debe tener 9 posiciones, de las cuales las primeras


deben ser dígitos y la última letra
valor=valor.toUpperCase();

Pattern mask = Pattern.compile("[0-9]{8,8}[A-Z]");

Matcher matcher = mask.matcher(valor);

if(!matcher.matches())

throw new ValidatorException(new FacesMessage("El


componente " + component.getId() + "

no contiene un NIF válido. Las 8 primeras


posiciones deben ser numéricas"));
String dni=valor.substring(0,8);
String digitoControl = valor.substring(8,9);
// Calculamos la letra de control
String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
int posicion_modulo = Integer.parseInt(dni)%23;
String digitoControlCalculado =
letras.substring(posicion_modulo,posicion_modulo+1);
if(!digitoControl.equalsIgnoreCase(digitoControlCalculado))
throw new ValidatorException(new FacesMessage("El
componente " + component.getId() +
" no contiene un NIF
válido"));
}
}

Registramos el nuevo Validador en el contexto de JSF.

Para ello, editamos el fichero descriptor WEB-INF/validaciones-config.xml e


insertamos las siguientes líneas:


<validator>

<validator-id>autentia.nifValidator</validator-id>
<validator-class>

com.autentia.tutorialValidacion.NifValidator

</validator-class>
</validator>

Creamos la página

La llamaremos validacion_nuestra.jsp y colgará de WebContent; su contenido


es el siguiente:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>


<html>

<head>

<title>AUTENTIA - TUTORIAL
VALIDACIONES/CONVERSIONES</title>

<link rel="stylesheet" type="text/css" href="css/estilos.css">

</head>

<body>

<f:view>

<h:form id="idUsuarios" name="gestionUsuariosBean">

<h:messages id="messageList" styleClass="error" showSummary="true"


showDetail="true" />

<h:panelGrid columns="2" styleClass="gestionUsuariosFormTable"

headerClass="gestionUsuariosFormHeader"

footerClass="gestionUsuariosFormFooter"

columnClasses="gestionUsuariosFormLabels,
gestionUsuariosFormInputs" width="600">

<!-- Nombre -->


<h:outputLabel for="login" value="Nombre"/>
<h:panelGroup>

<h:inputText id="nombre" styleClass="CajasTexto" size="30"


maxlength="100"

value="#{gestionUsuariosBean.nombre}">

<f:validateLength maximum="50" />

</h:inputText>

</h:panelGroup>

<!-- Nif -->

<h:outputLabel for="nif" value="Nif"/>


<h:panelGroup>

<h:inputText id="elNif" styleClass="CajasTexto" size="30"


maxlength="10"

value="#{gestionUsuariosBean.nif}" required="true">

<f:validator validatorId="autentia.nifValidator"/>
</h:inputText>

</h:panelGroup>

<h:panelGroup>

<h:commandButton action="resultado_validacion_nuestra"
value="Validar" />
<f:verbatim>&nbsp;</f:verbatim>
</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>
</body>
</html>

Añadimos en WEB-INF/validaciones-config.xml la navegabilidad para el botón


Validar:

<navigation-rule>

<from-view-id>/validacion_nuestra.jsp</from-view-id>

<navigation-case>

<from-outcome>resultado_validacion_nuestra</from-outcome>

<to-view-id>/resultado_validacion_nuestra.jsp</to-view-id>

<redirect/>
</navigation-case>
</navigation-rule>

….

Y creamos la página de resultados


WebContent/resultado_validacion_nuestra.jsp:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="t" %>

<html>

<head>

<title>AUTENTIA - TUTORIAL
VALIDACIONES/CONVERSIONES</title>

<link rel="stylesheet" type="text/css" href="css/estilos.css">

</head>

<body>

<f:view>

<h:form id="idUsuarios" name="gestionUsuariosBean">

<h:messages id="messageList" styleClass="error" showSummary="true"


showDetail="true" />

<h:panelGrid columns="2" styleClass="gestionUsuariosFormTable"

headerClass="gestionUsuariosFormHeader"

footerClass="gestionUsuariosFormFooter"

columnClasses="gestionUsuariosFormLabels,
gestionUsuariosFormInputs" width="600">

<!-- Nombre -->


<h:outputLabel for="login" value="Nombre"/>:
<h:panelGroup>

<h:outputText value="#{gestionUsuariosBean.nombre}"/>

</h:panelGroup>

<!-- Nif -->

<h:outputLabel for="nif" value="Nif"/>

<h:panelGroup>

<h:outputText value="#{gestionUsuariosBean.nif}"/>

</h:panelGroup>

<h:panelGroup>

<h:commandButton action="home" value="Volver" />

<f:verbatim>&nbsp;</f:verbatim>
</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>
</body>
</html>

Probamos

Desplegamos la aplicación en Tomcat y vemos cual es el resultado:


<p:confirmDialog message="Are you sure about destroying the world?"
header="Initiating destroy process" severity="alert"
widgetVar="cd">
<p:commandButton value="Yes Sure"
actionListener="#{buttonBean.destroyWorld}"
update="messages" oncomplete="confirmation.hide()"/>
<p:commandButton value="Not Yet" onclick="confirmation.hide();"
type=”button” />
</p:confirmDialog>

2
3 <?xml version="1.0" encoding="UTF-8"?>
4 <!--
5 To change this template, choose Tools | Templates
6 and open the template in the editor.
7 -->
8 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
9 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
10 <html xmlns="http://www.w3.org/1999/xhtml"
11 xmlns:ui="http://java.sun.com/jsf/facelets"
12 xmlns:h="http://java.sun.com/jsf/html"
13 xmlns:f="http://java.sun.com/jsf/core"
14 xmlns:p="http://primefaces.prime.com.tr/ui">
15
16 <body>
17 <div class="post">
18
19
20 <h2 class="title">Buscar Arquivo</h2>
21 <div id="stylized" class="myform">
22
23 <h:form>
24 <p>Coloque o valor no campo de busca.
25 Permite buca aninhada. Ex: Nome='Maria' e Caixa='20'
26 Busca todas as marias na caixa 20</p>
27 <h:outputLabel>Arquivo: <span class="small">Busca por n&uacute;mero do
28 Arquivo</span></h:outputLabel>
29 <h:inputText value="#{ArquivoControllerSearch.arquivo.id}"
30 required="false" />
31
32 <h:outputLabel>Nome do Aluno: <span class="small">Nome ou parte do
33 Nome</span></h:outputLabel>
34 <h:inputText value="#{ArquivoControllerSearch.arquivo.aluno}"
35 required="false" />
36
37 <h:outputLabel>RA: <span class="small">Busca por n&uacute;mero do
38 Registro</span></h:outputLabel>
39 <h:inputText value="#{ArquivoControllerSearch.arquivo.ra}"
40 required="false" />
41
42 <h:outputLabel>Caixa: <span class="small">Arquivos de uma
43 Caixa</span></h:outputLabel>
44 <h:inputText value="#{ArquivoControllerSearch.arquivo.caixa}"
45 required="false" />
46
47 <h:commandButton styleClass="button"
48 action="#{ArquivoControllerSearch.search}" value="Procurar" />
49 <h:commandButton styleClass="button" type="reset" value="Limpar" />
50
51
52 </h:form>

</div>
</div>

</body>
</html>

Obtención de la fila seleccionada en un datatable con JSF2.

0. Índice de contenidos.
• 1. Introducción.
• 2. Entorno.
• 3. Invocación al método getRowData.
• 4. Enviando el identificador del objeto como parámetro.
• 5. Enviando el objeto como parámetro.
• 6. Con el soporte de Jboss Seam.
• 7. Referencias.
• 8. Conclusiones.
1. Introducción
En este tutorial vamos a analizar las opciones que tenemos disponibles en JSF2 para obtener el
registro de la fila seleccionada en un dataTable.
La historia de usuario que queremos cumplir sería similar a esta: Como Pablo quiero acceder,
desde el listado de usuarios, a la edición de los mismos para modificar sus características
de acceso. Pablo es el administrador de usuarios en la aplicación de nuestro hipotético cliente.
Vamos a examinar todas las posibilidades de las que disponemos, que no son pocas, haciendo uso del
estandar, y con el soporte de anotaciones de Jboss Seam. Existen más posibilidades si hacemos uso
de librerías de componentes visuales de terceros como ICEfaces, RichFaces o Primefaces, pero dichas
posibilidades las vamos a examinar en otro tutorial en el que hablaremos de la posibilidad de selección
múltiple de filas de un dataTable.
Para el objetivo del tutorial, la selección de un registro de la fila puede suponer navegación a otra
vista o no, en función de si el evento de selección responde a un listener o a un action.

2. Entorno.
El tutorial está escrito usando el siguiente entorno:
• Hardware: Portátil MacBook Pro 17' (2.93 GHz Intel Core 2 Duo, 4GB DDR3 SDRAM).
• Sistema Operativo: Mac OS X Snow Leopard 10.6.1
• JSF2 (Mojarra 2.0.4)
• Jboss Seam 2.1 y RichFaces 3.3
• Apache Tomcat 7.0.6

3. Invocación al método getRowData.


La primera opción que vamos a examinar es la posibilidad de parametrizar a nivel de dataTable y
mediante el atributo binding, la referencia a un objeto del lado del managedBean. En dicho objeto,
representado por la clase UIData, se mantiene una referencia del dataTable que se almacena en el
árbol de componentes, que vive en el FacesContext durante toda la request.
De este modo, en la vista tendremos algo similar a lo siguiente:
view sourceprint?

01 <h:dataTable id="usersList"

02 var="user"

03 value="#{usersView.users}"

04 rows="10"

05 binding="#{usersView.usersDataTable}">

06 <h:column>
07 <f:facet name="header">

08 <h:outputText id="number_label"

09 value="#{msg['Users.login']}"/>

10 </f:facet>

<h:commandLink actionListener="#{usersView.editUser}"
11
immediate="true">

12 <f:ajax render="@form"/>

13 <h:outputText id="login"

14 value="#{user.login}"/>

15 </h:commandLink>

16 </h:column>

17 ...

18 </h:dataTable>

Y en el managedBean el método que responde al evento obtiene el registro seleccionado de la


siguiente forma:
view sourceprint?

01 @ManagedBean

02 @ViewScoped

03 public class UsersView {

04 ...

05 private UIData usersDataTable;

06
07 public void setUsersDataTable(UIData usersDataTable) {

08 this.usersDataTable = usersDataTable;

09 }

10

11 public UIData getUsersDataTable() {

12 return usersDataTable;

13 }

14 ...

15 public void editUser(ActionEvent event){

log.trace("User selected " + ((User)


16
usersDataTable.getRowData()) );

17 }

18 ...

19 }

20

Sería indiferente si trabajásemos con un action o con un actionListener, funciona con los dos tipos de
evento.

4. Enviando el identificador del objeto como parámetro.


También podemos enviar como parámetro el identificador del usuario, de modo que se añada al mapa
de parámetros de la request y obtenerlo desde el método correspondiente del managedBean.
Para ello desde la vista usamos el componente no visual <f:param
view sourceprint?

01 <h:dataTable id="usersList"

02 var="user"

03 value="#{usersView.users}"

04 rows="10">

05 <h:column>

06 <f:facet name="header">

07 <h:outputText id="number_label"

08 value="#{msg['Users.login']}"/>

09 </f:facet>

<h:commandLink actionListener="#{usersView.editUser}"
10
immediate="true">

11 <f:param name="userLogin" value="#{user.login}" />

12 <f:ajax render="@form"/>

13 <h:outputText id="login"

14 value="#{user.login}"/>

15 </h:commandLink>

16 </h:column>

17 ...

18 </h:dataTable>
En el método que recibe el evento podemos obtener el parámetro como sigue:
view sourceprint?

01 @ManagedBean

02 @ViewScoped

03 public class UsersView {

04 ...

05 private UIData usersDataTable;

06 ...

0
public void editUser(ActionEvent event){
7

final String userLogin =


0
FacesContext.getCurrentInstance().getExternalContext().getReques
8
tParameterMap().get("userLogin");

selectedUser =
09
FinancialService.getInstance().getByLogin(userLogin);

10 log.trace("User selected " + selectedUser );

11 }

12 ...

13 }

14

Aquí el inconveniente es que tenemos que volver a obtener el objeto totalmente poblado porque lo
que remitimos es su identificador y se trata de un tipo básico.
5. Enviando el objeto como parámetro.
Existe una alternativa a la de remitir el identificador que es la de remitir todo el objeto completo y,
para ello tenemos dos posibilidades.
La primera es hacer uso del componente no visual <f:setPropertyActionListener en el que le podemos
indicar el valor que tendrá un atributo del managedBean antes de que el evento de acción sea
invocado.
view sourceprint?

01 <h:dataTable id="usersList"

02 var="user"

03 value="#{usersView.users}"

04 rows="10">

05 <h:column>

06 <f:facet name="header">

07 <h:outputText id="number_label"

08 value="#{msg['Users.login']}"/>

09 </f:facet>

<h:commandLink actionListener="#{usersView.editUser}"
10
immediate="true">

11 <f:setPropertyActionListener value="#{user}"

target="#{usersView.selectedUser
12
}" />

13 <f:ajax render="@form"/>

14 <h:outputText id="login"

15 value="#{user.login}"/>
16 </h:commandLink>

17 </h:column>

18 ...

19 </h:dataTable>

Del lado del managedBean solo necesitaremos el atributo con sus métodos set & get.
view sourceprint?

01 @ManagedBean

02 @ViewScoped

03 public class UsersView {

04

05 ...

06 private User selectedUser;

07

08 public void setSelectedUser(User selectedUser) {

09 this.selectedUser = selectedUser;

10 }

11

12 public User getSelectedUser() {

13 return selectedUser;

14 }
15 ...

16 }

17

La segunda opción, solo podremos hacer uso de ella, si tenemos disponible la versión 2.2 de EL, como
en nuestro caso que usamos Tomcat 7.
Consiste en invocar directamente desde Expression Language a un método del managedBean
pasándole un parámetro.
view sourceprint?

01 <h:dataTable id="usersList"

02 var="user"

03 value="#{usersView.users}"

04 rows="10">

05 <h:column>

06 <f:facet name="header">

07 <h:outputText id="number_label"

08 value="#{msg['Users.login']}"/>

09 </f:facet>

<h:commandLink action="#{usersView.editUser(user)}"
10
immediate="true">

11 <f:ajax render="@form"/>

12 <h:outputText id="login"

13 value="#{user.login}"/>
14 </h:commandLink>

15 </h:column>

16 ...

17 </h:dataTable>

De este modo, en el managedBean, tendríamos simplemente el método con dicho parámetro de


entrada.
view sourceprint?

01 @ManagedBean

02 @ViewScoped

03 public class UsersView {

04 ...

05 public void editUser(User user){

06 selectedUser = user;

07 log.trace("User selected " + selectedUser );

08 }

09 ...

10 }

11

Esta técnica es la que veníamos usando hasta ahora en los proyectos que tenían el soporte de Jboss
Seam que sí permitía invocar a un método del managedBean pasándole parámetors de entrada.
6. Con el soporte de Jboss Seam.
Además de la que hemos comentado anteriormente existe una segunda posibilidad en Jboss Seam
consistente en mantener en el managedBean un atributo anotado que tendrá una referencia al
dataTable y un segundo atributo, también anotado, que mantiene una referencia a la fila seleccionada.
view sourceprint?

01 @Name("usersView")

02 @Scope(ScopeType.SESSION)

03 public class UsersView {

04

05 @DataModel

06 List<User> users;

07

08 @DataModelSelection

09 User selectedUser;

10

11 ...

12 }

La vista no requiere de ninguna configuración adicional, desde cualquier método de evento del
managedBean podemos acceder al atributo que estará poblado con la entidad de la fila seleccionada.
view sourceprint?

1 ...

2 <rich:dataTable id="usersList"

3 var="user"

4 value="#{usersView.users}"
5 rows="10">

You might also like