lunes, 29 de septiembre de 2008

JSF - Parámetros al bean y entre beans

Cuando un método es invocado a través de una propiedad action nos encontramos con que dicho método no puede recibir parámetros. Ésto representa un problema cuando producimos un listado de elementos con un enlace en cada uno para, por ejemplo, visualizar el detalle del elemento.

Existen dos formas de saber que elemento se ha seleccionado:
  • Pasando un parámetro con y recogiéndolo en el método action con la llamada:
FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get("idDelParametro").
  • Accediendo al control tabla en la parte servidor y obteniendo el objeto de negocio asociado a su fila seleccionada:
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();
UIData table = (UIData)root.findComponent(“idDelFormulario”).
findComponent(“idDeLaTabla”);
ObjetoNegocio seleccionado = (ObjetoNegocio)table.getRowData();
Por otro lado, para pasar el objeto seleccionado al bean asociado a la siguiente página podemos aplicar tres métodos. Estos trozos de código habría que añadirlos en el método que procese el action que provoque el cambio de página. Justo después de ellos devolveríamos la cadena que hace que se navegue a la siguiente vista:
  • Utilizar el mismo bean para las dos páginas y guardarlo en sesión, quedándonos una copia del objeto seleccionado dentro de un atributo del bean:
this.objetoActivo = seleccionado;
  • Guardar en la petición el objeto seleccionado para que el siguiente bean lo recupere en un getter al inicializar la página:
HttpServletRequest request = (HttpServletRequest)
facesContext.getExternalContext().getRequest();
request.setAttribute("objetoActivo", seleccionado );
  • Acceder desde el API JSF al siguiente bean y pasarle el objeto explícitamente:
FacesContext FCInstance = FacesContext.getCurrentInstance();
String theBeanName = "informeManager";
Bean bean = (Bean) FCInstance
.getELContext().getELResolver().getValue(
FCInstance.getELContext(), null, theBeanName);
bean.setObjetoActivo(seleccionado);
Es importante darse cuenta de que cuando se usa dicho método, no es necesario que el bean “siguienteBean” este en sesión, sino que JSF lo creara, si es necesario, al llamar a Util.getValueBinding() (al estilo de como lo hacen los tags JSF).
Por otro lado, si los beans están en sesión, puede ser deseable, al llamar al setter, pasar un clon del objeto seleccionado, en lugar del objeto seleccionado en si. De esta forma evitamos que cambios en la página de detalle se propaguen al listado.

5 comentarios:

michael_demonio dijo...

saludos, amigo cómo puedo enviar un parámetro a un método ke se invoca desde un jsf, necesito enviarle una cadena para luego hacer una consulta en la base d datos con esa cadena y retornar una lista
muchas gracias de antemao, espero me puedas ayudar
mi correo es hollowlife7@gmail.com

Anónimo dijo...

Fino,
me sirvió...

Cristina GainsBourg dijo...

En una palabra GRACIAS :)

Anónimo dijo...

Muchas gracias, que crack!!

Anónimo dijo...

¡¡Muchas gracias!! Me ha servido de mucho. He tenido que hacer alguna modificación, pero ha conseguido desbloquear un problema grande que tenía.

Por si a alguno le sirve finalmente mi código ponía:

En origenBean.java:


import javax.servlet.http.HttpServletRequest;
import javax.faces.context.FacesContext;

...
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
request.setAttribute("objetoActivo", seleccionado);


En destinoBean.java:
import javax.servlet.http.HttpServletRequest;
import javax.faces.context.FacesContext;

...
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
objetoSeleccionado = request.getAttribute("objetoActivo");


En el primer Bean me pasa el objeto que he seleccionado y el segundo lo captura y en función de eso puede mostrar un listado de detalle. Gracias otra vez y adelante con tu blog!