Transporte de dados entre managed beans [RESOLVIDO]

6 respostas
gtludwig

pessoal,

Ainda estou com dificuldades em mandar dados entre managed beans. Todos os managed beans estão com escopo de request.

Minha aplicação "começa" com a seguinte (trecho de) página:
<ui:define name="core">
	<h:inputHidden value="#{anamanNewStudyMB.idRegister}" />
		<rich:panelBar>
			<a4j:form>
				<rich:column>
					<rich:panel rendered="true">
						<a4j:commandButton value="Selecionar classificação"
							action="#{anamanNewStudyMB.selectRegister}" />
					</rich:panel>

// outros <rich:panel /> com que são renderizados na seqüência de operação do sistema.

				</rich:column>
			</a4j:form>
		</rich:panelBar>
</ui:define>

O chama uma página que deveria retornar um id para esse o managed bean que controla essa página com botões. A idéia é que o receba um int que deve ser passado à próxima página (em um botão oculto agora).

O problema está no momento de retornar o valor que foi selecionado corretamente na página que é acessada pelo botão "Selecionar classificação". Estou tentando mandar o valor do idRegister que preciso assim:

public void returnIdRegister() {
	rIL = ars.getRegisterIdListByDesc(selectedRefDesc);
	System.out.println("selectedRefDesc: " + selectedRefDesc);
	for (AnamanRegister reg : rIL) {
		int idReg = reg.getIdRegister();
		if(rIL.size() == 1 && idReg != 0) {
			System.out.println("send idReg: " + idReg);
			anamanNewStudyMB.setIdRegister(idReg);
		}
	}
}
Esse método é disparado por um botão definido como:
<a4j:commandButton 
	value="#{bundle['anamanButton.submit']}"
	type="submit" 
	action="#{anamanRegisterMB.returnIdRegister}" />
E me estoura o seguinte java.lang.NullPointerException
selectedRefDesc: Aparelho de Anestesia
send idReg: 8
16/11/2009 18:26:33 com.sun.faces.application.ActionListenerImpl processAction
SEVERE: java.lang.NullPointerException
javax.faces.el.EvaluationException: java.lang.NullPointerException
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:387)
	at org.ajax4jsf.component.AjaxActionComponent.broadcast(AjaxActionComponent.java:55)
	at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:324)
	at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:299)
	at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:256)
// continua ...

Caused by: java.lang.NullPointerException
	at anaman.mb.AnamanRegisterMB.returnIdRegister(AnamanRegisterMB.java:481)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
// continua ...

	at java.lang.Thread.run(Thread.java:619)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	... 28 more
Caused by: java.lang.NullPointerException
	at anaman.mb.AnamanRegisterMB.returnIdRegister(AnamanRegisterMB.java:481)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
// continua ...

SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
	at anaman.mb.AnamanRegisterMB.returnIdRegister(AnamanRegisterMB.java:481)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)

Então, eu sei que o problema é no método returnIdRegister(),mas não sei o que é...

Obrigado desde já!
Gustavo

6 Respostas

thimor

Opa, olha nois aqui dnovo.
blz?

Seguinte para vc passar o parametro via request vc precisa dizer qual parametro vc esta passando. utilizando a tag <f:param>

//Seu botao que seleciona o id tem que ficar assim.
<a4j:commandButton value="#{bundle['anamanButton.submit']}" type="submit" action="#{anamanRegisterMB.returnIdRegister}">
     <f:param name="idRegister" value="#{anamanNewStudyMB.idRegister}"/>
<a4j:commandButton>

Outra coisa que notei que vc fez errado é a assinatura do metodo. Se voce estiver usando um metodo void no bean tem q ser acionado por uma actionListener na pagina. ou seja seu botao teria que ser assim:

<a4j:commandButton value="#{bundle['anamanButton.submit']}" type="submit" actionListener="#{anamanRegisterMB.returnIdRegister}">
     <f:param name="idRegister" value="#{anamanNewStudyMB.idRegister}"/>
<a4j:commandButton>

//A assinatura do metodo tb muda tem q ser assim
public void returnIdRegister(ActionEvent evento) { ... }

se vc estiver usando action a assinatura do metodo deve ser assim:

public String returnIdRegister() { return "alguma coisa" }

para concluir como vc passou o parametro via request no seu metodo tem q ter uma coisa antes.

public String returnIdRegister() {
    String str = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("idRegister"); // <-----  
   //vc pega a str e faz as comparacoes depois, pois nao to entendendo esse seu metodo.

    rIL = ars.getRegisterIdListByDesc(selectedRefDesc);  
    System.out.println("selectedRefDesc: " + selectedRefDesc);  
    for (AnamanRegister reg : rIL) {  
        int idReg = reg.getIdRegister();  
        if(rIL.size() == 1 && idReg != 0) {  
            System.out.println("send idReg: " + idReg);  
            anamanNewStudyMB.setIdRegister(idReg);  
        }  
    }  
    return "a pagina de destino";
}

faz assim q da certo.

gtludwig

Olá thimor!

Tudo certo! Realmente agora que eu estou revendo o código (muito feio, por sinal!) compreendo o que o cansaço e a pressa fazem com o ser humano...

Não sei se é correta a abordagem, mas tenho procurado usar o actionListener em comboBoxes ou checkBoxes por que a mudança de valor é um evento mais evidente.

public String returnIdRegister() {
    String str = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("idRegister"); // <-----  
   //vc pega a str e faz as comparacoes depois, pois nao to entendendo esse seu metodo.
...

Apesar de ter quase certeza que o retorno da lista rIL sempre será somente 1, a idéia é garantir que somente 1 valor seja passado para o outro managed bean.

Voltando, alí eu peguei a String str, mas nesse momento ela é vazia, correto? Afinal o idRegister só é populado mais abaixo, não?

Obrigado!

thimor

esse codigo q eu coloquei vc coloca ele no metodo que da o get no campo do formulario. como eu tinha dito, nao sei se era aquele codigo.

eu costumo criar um metodo

public String getRequestParameter(String key) {
    return FacesContext.getCurrentInstance().getExtenalContext().getRequestParameterMap().get(key);
}

ai sempre que vc quiser pegar algum parametro q foi passado por request vc chama o metodo passando o nome q vc deu a ele na tela.

gtludwig

thimor,

Agora eu entendi, mas minha situação é diferente…

Esse seu método retorna o valor de um parâmetro colocado na request pela <f:param name="" value="" />.

Estou pensando que eu preciso desse método, sim, mas no managed bean de destino. O que acontece é que quando clico naquele botão, o método é disparado, mas o botão em si não retorna o id que eu preciso mandar para a próxima tela. Esse id é populado no método

public String returnIdRegister() { rIL = ars.getRegisterIdListByDesc(selectedRefDesc); for (AnamanRegister reg : rIL) { int idReg = reg.getIdRegister(); if(rIL.size() == 1 && idReg != 0) { //anamanNewStudyMB.setIdRegister(idReg); afu.setRequestMapValue("idRegister", idReg); // aqui tentei colocar um map na request para que eu possa pegar o valor no outro managed bean } } return "registerOK"; // navigation rule }

e eu tenho, então um método utilitário para jogar o valor num RequestMapValue assim:

public void setRequestMapValue(String key, Object value) { FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(key, value); }

hmm… acabei de ter uma idéia aqui… já posto o resultado…

thimor

vc pode entao fazer um metodo void e utilizaro requestdispatcher. mas o metodo de colocar o atributo ta certo.

gtludwig

então, consegui o que eu queria…

no primeiro managed bean coloquei isso aqui:

public int getIdRegister() { int reg = anamanRegisterMB.getRegisterId(); if (reg != 0) { idRegister = reg; } return idRegister; }

na segunda página coloquei isso:

<h:inputHidden value="#{anamanRegisterMB.registerId}" />

e no managed bean da segunda página, deixei o método assim:

public String returnIdRegister() { rIL = ars.getRegisterIdListByDesc(selectedRefDesc); for (AnamanRegister reg : rIL) { int idReg = reg.getIdRegister(); if(rIL.size() == 1 && idReg != 0) { setRegisterId(idReg); } } return "registerOK"; // navigation rule }

aparentemente está funcionando!!!

valeu a ajuda (de novo!),
abraço,

Gustavo

então, toda vez que o método atualiza o idRegister, o primeiro managed bean pega a alteração

Criado 16 de novembro de 2009
Ultima resposta 16 de nov. de 2009
Respostas 6
Participantes 2