sábado, 13 de febrero de 2010

Acceder a ManagedBean desde otro ManagedBean en JSF 2.0

Cuando se trabaja con variables sesión en JSP/Servlets es fácil guardar estas variables y también accederlas... bueno, al menos para quien ha trabajado bastante con este tipo de variables de sesión: Desde un servlet se debería escribir

request.setAttribute("obj1",obj1);

... cuando se desea guardar una variable de sesión de alcance "request".Para uno de alcance "sesión" es una historia similar.

Y desde un JSP para acceder a esta variable de sesión, usando EL, deberíamos usar algo como esto:
 Mostrando objeto: ${ob1}


Pero en JSF (en especial la versión 2.0), ya no se debería utilizar variables de sesión ya que JSF propone ManagedBeans que tengan alcance Scope, Request, Application, Custom y none. Pues bien, esto funcionaría así.

Un ManagedBean:
@ManagedBean(name="bean1")
@SessionScoped
public class Bean1 {

    public Bean1() {
    }
    private String nombre;

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

}

Y para accederlo desde una página JSF, debería ser así:

<?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:form>
            Nombre:<h:inputText value="#{bean1.nombre}" />
            <br/><h:commandButton value="Guardar" />
        </h:form>
    </h:body>
</html>

Todo normal.. y si accedemos desde otra página, bastaría con escribir #{bean1.nombre}

Hasta ahí todo normal y muy bien.. pero que pasaría si tenemos otro managedBean y queremos acceder al primer managedBean?

Pues bien, se debería declarar una propiedad (con set/get) del tipo del primer ManagedBean, y agregarle la anotación @ManagedProperty("#{bean1}") (Donde bean1 es el nombre del otro managedbean. Y listo!! solo usar.

@ManagedBean(name = "bean2")
@RequestScoped
public class Bean2 {

    @ManagedProperty("#{bean1}")
    private Bean1 bean1;

    /** Creates a new instance of Bean2 */
    public Bean2() {
    }

    public String getSaludo() {
        return "Hola " + bean1.getNombre();
    }

    public Bean1 getBean1() {
        return bean1;
    }

    public void setBean1(Bean1 bean1) {
        this.bean1 = bean1;
    }

    
}

El código fuente de este ejemplo se encuentra aquí: http://diesil-java.googlecode.com/files/ScopesJSF20.tar.gz


10 comentarios:

  1. Gracias! justo lo que estaba buscando.

    ResponderEliminar
  2. thanks frien por el dato me sirvio de mucho para mi proyecto

    ResponderEliminar
  3. Hi y cuando se desea eliminar estos objetos de la session???

    ResponderEliminar
  4. Tienes dos maneras, que hacen lo mismo:

    Desde un servlet:

    HttpSession session = request.getSession();
    session.invalidate();

    Desde un ManagedBean:
    FacesContext ctx = FacesContext.getCurrentInstance();
    HttpSession session = (HttpSession) ctx.getExternalContext().getSession(false);
    session.invalidate();

    ResponderEliminar
  5. Gracias amigo :) increible que sea tan simple...

    ResponderEliminar
  6. si tengo ambos beans como @SessionScoped puedo hacer esto de la misma manera?

    ResponderEliminar
  7. ya lo probe y si funciona de la misma manera
    Muchas gracias :)

    ResponderEliminar
  8. Estaba buscando la aclaración sobre este concepto básico de DI, y este tutorial me ha sido de gran ayuda. Gracias.

    ResponderEliminar

Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups


Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/