JSF - ManagedBean dentro de ManagedBean

   
Vista:

ManagedBean dentro de ManagedBean

Publicado por Fabián (1 intervención) el 01/05/2014 18:38:27
Hola, no estoy muy seguro de que esto se pueda hacer pero bueno, a ver si alguien pudiera echarme una manilla.

Tengo un managed Bean que se llama LoginManagedBean y otro Managed Bean que se llama AccionManagedBean. La idea es que cuando alguien realice una acción "crítica" en el sistema (Loguearse correctamente, loguearse mal, crear un usuario, eliminar un usuario, etc) El sistema registra la IP, MAC, fecha y hora del suceso además de una descripción.

La cosa es que intento que cuando hago el login se invoque un método que está definido en AccionManagedBean desde el código de LoginManagedBean.

Queda una cosa así:

(La siguiente función está dentro de LoginManagedBean)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public String doLogin(){
        String status_login = "LOGIN_ERROR";
       if (this.getUser().length()>0 && this.getPass().length()>0){
            Usuario u = this.usuariofacade.findForLogin(this.getUser(), this.getPass());
 
            if (u==null){
 
                this.accion.addAccion("Intento de logueo erróneo para el usuario "+this.getUser(), -1);
                this.setMensajeSalida("Usuario no encontrado");
 
            }else{
                this.accion.addAccion("Usuario "+this.getUser()+" inicia sesión.", u.getIdentificador());
                this.setMensajeSalida("Usuario encontrado correctamente");
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("USUARIO", u);
 
                status_login = "LOGIN_OK";
            }
 
       }else{
           this.setMensajeSalida("Debe rellenar ambos campos");
       }
 
       return status_login;
    }


La variable accion está definida de la siguente manera:

1
AccionManagedBean accion = new AccionManagedBean();


Y la función addAccion es la siguiente:

(La siguiente función está dentro de AccionManagedBean)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void addAccion(String descripcion, int fkUsuario){
        try{
 
                this.accionRealizada = new Accion();
 
                if (this.accionFacade==null)
                    this.accionFacade = new AccionFacade();
 
                this.accionRealizada.setDescripcion(descripcion);
                this.accionRealizada.setFechaHora(new Date());
                this.accionRealizada.setIpMaquina(this.getIPMaquina());
                this.accionRealizada.setMac(this.getMAC());
                this.accionRealizada.setFkUsuario(fkUsuario);
 
                this.accionFacade.create(this.accionRealizada);
 
                System.out.println("Acción registrada correctamente - "+descripcion);
        }catch(NullPointerException ex2){
                System.err.println("Se ha producido un error a la hora de registrar la acción realizada por el usuario (2).");
                ex2.printStackTrace();
        }catch(Exception ex){
                System.err.println("Se ha producido un error a la hora de registrar la acción realizada por el usuario.");
                ex.printStackTrace();
 }


accionFacade está definida como el Facade de la entidad Accion y accionRealizada es una Accion() inicializadas en el public AccionManagedBean() de esta manera:

1
2
3
4
5
6
7
8
9
public AccionManagedBean() {
        System.out.println("Llamada a acción managed bean.");
        if (this.getAccionRealizada()==null)
            this.setAccionRealizada(new Accion());
 
        if (this.getAccionesRealizadas()==null){
            this.setAccionesRealizadas(new ArrayList());
        }
    }



Si llamo a la función addAccion desde el xhtml poniendo por ejp: #{accionManagedBean.addAccion("Acceso a web login", 0)} funciona correctamente.

Pero si llamo a la función addAccion desde el ManagedBean tal y como está en la función doLogin me lanza un NullPointerException. La cosa es que he comprobado a ver si el accionFacade o el accionRealizada eran Null antes del create y no son NULL.

El managed bean de Login está definido como @SessionScoped y el de accion está definido como @RequestScoped

La excepción que lanza es la siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Grave:   java.lang.NullPointerException
	at app.dao.AbstractFacade.create(AbstractFacade.java:26)
	at app.beans.AccionManagedBean.addAccion(AccionManagedBean.java:61)
	at app.beans.LoginManagedBean.doLogin(LoginManagedBean.java:57)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at javax.el.ELUtil.invokeMethod(ELUtil.java:326)
	at javax.el.BeanELResolver.invoke(BeanELResolver.java:536)
	at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:269)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
	at java.lang.Thread.run(Thread.java:744)




No sé que más información puede ser útil. La cosa es que como digo si la llamada lo hago desde el xhtml funciona correctamente y registra la acción, pero si lo hago desde el ManagedBean lanza esa excepción. La pregunta sería saber si es posible llamar desde un ManagedBean a un método que está definido en otro ManagedBean y si se puede pues saber qué puedo estar haciendo mal.

Gracias a todos por la ayuda,
Un saludo.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

ManagedBean dentro de ManagedBean

Publicado por juan (7 intervenciones) el 09/05/2014 17:40:11
Hola Fabián, espero te encuentres bien. Yo manejo todos los bean necesitados en un form embebidos en el bean que maneja el form. Esto se conoce como inyección de beans y hay unas reglas para tener en cuenta.

lo primero es que debes poner el bean disponible para que se pueda usar dentro de otro, por ejemplo

este es un bean que usa varios:

el paquete que nos dice la ruta del bean como normalmente lo hacemos cuando creamos un bean
package ....

estos son los bean usados dentro del bean que maneja el form y los hacemos visibles
con su ruta
import com.armar.classes.document.ClsDocument;
import com.armar.classes.languages.ClsMessage;
el bean que tu quieres inyectar se llama AccionManagedBean entonces sería asi suponiendo que esta en esta ruta
import com.armar.classes.model.AccionManagedBean;
import com.armar.classes.security.ClsUser;
y puedes seguir inyectando beans los que quieras

y estos ya son import que todos usamos normalmente
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

si tu bean se llama LoginManagedBean yo configuro el managed de esta forma, supongo que tu lo haces en un xml y de igual forma servirá
@ManagedBean(name = "loginManagedBean")
@ViewScoped
Cuidado con esto, el view scoped, session scoped, etc, es importante el orden para que funcionen, al final te explico

public class LoginManagedBean implements Serializable{
/**
* Aqui estoy activando un bean de administracion de usuarios que es sessionscoped que definí en los import
*/
@ManagedProperty(value = "#{clsUser}")
private ClsUser clsUser = new ClsUser();

/**
* Aqui inyecto un ena de documentos que es viewscoped
*/
@ManagedProperty(value = "#{clsDocument}")
private ClsDocument clsDocument = new ClsDocument();

/**
* Aqui inyecto un bean de mensajes que es sessionscoped, asi se definió en el bean
*/
@ManagedProperty(value = "#{clsMessage}")
private ClsMessage clsMessage = new ClsMessage();

/**
* Aqui inyecto tu bean AccionManagedBean Y DEBERIA SER VIEWSCOPED O SUPERIOR PARA QUE FUNCIONE
*/
@ManagedProperty(value = "#{accionManagedBean}")
private ClsMessage accionManagedBean = new AccionManagedBean();


y después de esto debes encapsular estas variables que se refieren a los bean inyectados (en netbeans click derecho a la pantalla: refactor-encapsulate fields y allí seleccionas las variables)
para el caso del bean clsuser

/**
* @return the clsUser
*/
public ClsUser getClsUser() {
return clsUser;
}

/**
* @param clsUser the clsUser to set
*/
public void setClsUser(ClsUser clsUser) {
this.clsUser = clsUser;
}

y para el caso de tu bean AccionManagedBean
/**
* @return the accionManagedBean
*/
public AccionManagedBean getAccionManagedBean() {
return accionManagedBean;
}

/**
* @param accionManagedBean the accionManagedBean to set
*/
public void setAccionManagedBean(AccionManagedBean accionManagedBean) {
this.accionManagedBean = accionManagedBean;
}


y cuando uses tu referencia en el form :
"#{loginManagedBean.accionManagedBean.campoofuncionquenecesitas}"

SI TIENES UN BEAN PRINCIPAL LoginManagedBean SESSIONSCOPED, SOLO LE PUEDES INYECTAR BEAN SESSIONSCOPED O SUPERIORES

EN NUESTRO EJEMPLO, EL LoginManagedBean ES VIEWSCOPED Y COMO VES INYECTO BEANS VIEWSCOPED O SUPERIORES COMO EL SESSIONSCOPED, PERO NO LE PUEDO INYECTAR REQUESTSCOPED

EN TU PROGRAMA TE SACARA ERROR PORQUE EL SESSIONSCOPED NO PUEDE INYECTARSE BEAN INFERIORES, COMOEL CASO DEL REQUESTSCOPED.

PARA UN SESSION PUEDES INYECTAR EL SESSION Y EL APPLICATIONSCOPED

SE QUE SOY MUY ENREDADO EXPLICANDO PERO SI TIENES DUDAS CON GUSTO LAS RESOLVERÉ

suerte
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar