[RESOLVIDO]javax.el.ELException with message: "java.lang.NullPointerException"

0 respostas
S
Olá comunidade.

Estou com um pequeno probleminha em minha aplicação. Estou desenvolvendo um módulo onde o usuario poderá renovar sua senha de validação e tenho o seguintes códigos. Lembrando que estou usando JSF e JBoss Seam.

Segue um JavaBean Recuperar Senha, onde tenho apenas métodos acessores
package br.ibict.bibliotecavirtual.service;

import java.io.Serializable;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;


@Name("recuperarSenha")
@Scope(ScopeType.SESSION)
public class RecuperarSenha implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 735937576058996679L;
	private String novaSenha;
	private String confirmarNovaSenha;
	
	
	
	public RecuperarSenha(){}
		
		
	
	public String getNovaSenha() {
		return novaSenha;
	}
	public String setNovaSenha(String novaSenha) {
		return this.novaSenha = novaSenha;
	}
	public String getConfirmarNovaSenha() {
		return confirmarNovaSenha;
	}
	public void setConfirmarNovaSenha(String confirmarNovaSenha) {
		this.confirmarNovaSenha = confirmarNovaSenha;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((confirmarNovaSenha == null) ? 0 : confirmarNovaSenha
						.hashCode());
		result = prime * result
				+ ((novaSenha == null) ? 0 : novaSenha.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RecuperarSenha other = (RecuperarSenha) obj;
		if (confirmarNovaSenha == null) {
			if (other.confirmarNovaSenha != null)
				return false;
		} else if (!confirmarNovaSenha.equals(other.confirmarNovaSenha))
			return false;
		if (novaSenha == null) {
			if (other.novaSenha != null)
				return false;
		} else if (!novaSenha.equals(other.novaSenha))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "RecuperarSenha [confirmarNovaSenha=" + confirmarNovaSenha
				+ ", novaSenha=" + novaSenha + "]";
	}
		
	
}

Agora o método em meu ManagedBean onde ele efetua a troca da senha.

@SuppressWarnings("unchecked")
	@End
	public String salvarNovaSenha(){
		String senha = usuarioLogado.getSenha();
		Query query = entityManager.createQuery("select u from Usuario u where u.senha = :senha");
		query.setParameter("senha", senha);
		List<Usuario> buscaSenha = (List<Usuario>) query.getResultList();
		for(int i=0; i < buscaSenha.size();i++){
			Usuario us = entityManager.find(Usuario.class, buscaSenha.get(i).getId());
			if(us.equals(usuario.getId())){
				usuarioLogado.setSenha(null);
				entityManager.merge(us);
				entityManager.flush();
		
			}
			
		}
	
		recuperarSenha.setNovaSenha(guardaNovaSenha);
		recuperarSenha.setConfirmarNovaSenha(guardaConfirmacaoSenha);
		String novaSenha = recuperarSenha.getNovaSenha();
		String confirmaSenha = recuperarSenha.getConfirmarNovaSenha();
			
		if(novaSenha.equals(confirmaSenha)){
			
			usuario.setSenha(novaSenha);
			entityManager.merge(usuario);
			entityManager.flush();
			facesMessages.add("Nova Senha atualizada com sucesso");
		} else {
			facesMessages.add("Nova Senha e Confirmar Senha devem ser iguais");
			return "";
		}
e por fim meu Backing Bean JSF
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:s="http://jboss.com/products/seam/taglib"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:a="http://richfaces.org/a4j"
	xmlns:rich="http://richfaces.org/rich"
	template="/layout/template.xhtml">

	<ui:define name="body">
		<h:form id="trocaSenha" styleClass="edit">
		<rich:panel
				style="background-color: #{layoutManager.carregaConfiguracao('color.background.table.edit')};">
				<f:facet name="header">Nova Senha</f:facet>
				<s:decorate id="senhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Senha Atual</ui:define>
					<h:inputText id="senhaAntiga" size="20" maxlength="20" value="#{usuario.senha}" 
					style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
					font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
					font-family: #{layoutManager.carregaConfiguracao('font.text.input')}; " />
				</s:decorate>
				
				<s:decorate id="novaSenhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Nova Senha</ui:define>
					<h:inputText id="novaSenha" required="true" size="20" maxlength="20"
						value="#{recuperarSenha.novaSenha}"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')};"/>
				</s:decorate>
				
				<s:decorate id="confirmaSenhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Confirmar Senha</ui:define>
					<h:inputText id="confirmaSenha" size="20" maxlength="20"
						value="#{recuperarSenha.confirmarNovaSenha}" 
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')}; "/>
				</s:decorate>
				
				<div style="clear: both"><span class="required">*</span>
				Campos obrigatórios</div>
			</rich:panel>
			<div class="actionButtons">
	<s:button id="salvarnovaSenha" value="Salvar" action="#{usuarioManager.salvarNovaSenha}"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')}; "/>
			
			<s:button id="cancelar" value="Cancelar" propagation="end" view="/home.xhtml"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')}; "/>
			</div>
			</h:form>
		</ui:define>
	</ui:composition>

O problema é o seguinte amigos, não estou conseguindo pegar os dados da view jsf através dos gets and sets dos atributos da minha classe RecuperarSenha.java, uma coisa simples mas que eu já debuguei várias vezes e não estou conseguindo enxergar o erro.
Se alguém já passou por esta situação e puder me ajudar fico muito grato.

Olá pessoal.

Quero agradecer as 62 visitas até agora registradas e volto a esse post para dizer-lhe que consegui a solucionar esse pequeno problema. Então vamos as explicações para se caso pintar um novo post com esse mesmo problema, possa servir para acender uma luz no fim do túnel para outros.

1º - Cada coisa no seu lugar.

Tive que rever o meu POJO e coloca-lo em um pacote chave. Um pacote de serviços da aplicação, pois como já tinha uma Entity Bean Usuarios onde ao se cadastrar o mesmo já salva uma senha, precisava apenas manipular os atributos dessa minha classe para fazer a operação desejada, que era simplesmente trocar a senha.
Com relação ao escopo de contexto, mudei para o CONVERSATION, pois o usuario em sua natureza já ocupa um escopo de SESSION.

package br.ibict.bibliotecavirtual.service;

import java.io.Serializable;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

//import br.ibict.bibliotecavirtual.entity.Usuario;


@Name("recuperarSenha")
@Scope(ScopeType.CONVERSATION)
public class RecuperarSenha implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 735937576058996679L;
	
	private String novaSenha;
	private String confirmaNovaSenha;
	


	public String getNovaSenha() {
		return novaSenha;
	}



	public void setNovaSenha(String novaSenha) {
		this.novaSenha = novaSenha;
	}



	public String getConfirmaNovaSenha() {
		return confirmaNovaSenha;
	}



	public void setConfirmaNovaSenha(String confirmaNovaSenha) {
		this.confirmaNovaSenha = confirmaNovaSenha;
	}



	@Override
	public boolean equals(Object obj) {
		return super.equals(obj);
	}



	@Override
	public int hashCode() {
		return super.hashCode();
	}



	@Override
	public String toString() {
		return super.toString();
	}
			
	
}

Antes o método que fazia essa troca estava no Managed Bean que gerencia o CRUD da Entity Bean Usuario, então resolvi criar um Managed Bean que gerencia-se as Actions relacionadas a classe de serviço acima criada. E assim futuramente posso implementar um método nessa mesma classe na qual se o usuário esquecer a senha, ele poderá receber uma senha padrão e depois trocar a senha. Segue abaixo a classe:

package br.ibict.bibliotecavirtual.session;

import javax.persistence.EntityManager;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;

import br.ibict.bibliotecavirtual.entity.Usuario;
import br.ibict.bibliotecavirtual.service.RecuperarSenha;

@Name("recuperarsenhaManager")
@Scope(ScopeType.CONVERSATION)
public class RecuperarSenhaManager {
	
	
	@In(required=false)
	@Out(required=false)
	private RecuperarSenha recuperarSenha = new RecuperarSenha();
	
	
	
	@In(required=false)
	private Usuario usuario = new Usuario();
	
	@In
	private EntityManager entityManager;
	
	@In
	private FacesMessages facesMessages;
	
	private String novaSenha;
	private String confirmarSenha;
	
	
	
	
	
	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public String getNovaSenha() {
		return novaSenha;
	}

	public void setNovaSenha(String novaSenha) {
		this.novaSenha = novaSenha;
	}

	public String getConfirmarSenha() {
		return confirmarSenha;
	}

	public void setConfirmarSenha(String confirmarSenha) {
		this.confirmarSenha = confirmarSenha;
	}



	
/*	public boolean armazenaNovaSenha(String senha, String confirmaSenha){
		
		String guardaSenha = senha;
		String guardaConfirmaSenha = confirmaSenha;
		usuario.setSenha(guardaSenha);
		usuario.setConfirmaSenha(guardaConfirmaSenha);
		if(usuario.getSenha().equals(guardaConfirmaSenha)){
			return true;
		}
		else{
			return false;
		}
		
	}*/

	//Método para salvar a nova senha no banco de dados
	@End
	public String salvarNovaSenha(String senha, String confirmaSenha){
		
		//Armazena o valor do parâmetro na variavel guardaSenha
		String guardaSenha = senha;
		//Armazena o valor do parâmetro na variável guardaConfirmaSenha
		String guardaConfirmaSenha = confirmaSenha;
		//Objeto recebe o valor da variável guardaSenha
		usuario.setSenha(guardaSenha);
		//Objeto recebe o valor da variável guardaConfirmaSenha
		usuario.setConfirmaSenha(guardaConfirmaSenha);
		//Se senha e confirma senha foram iguais, então
		if(usuario.getSenha().equals(usuario.getConfirmaSenha())){
			//Atualiza a senha do usuário no banco
			entityManager.merge(usuario);
			//Sincroniza a atualização feita na base de dados
			entityManager.flush();
			//Exibe mensagem na tela
			facesMessages.add("Nova senha atualizada com sucesso");
		}
		else{
			facesMessages.add("Senha e confirmação de senha apresentam valores diferentes.");
		}		
		
		
		return "salvarNovaSenha";
	}

}

2 - "Dando nome aos bois":

Outra coisa também que não estava legal em meu backing bean JSF, era o nome dado ao e aos objetos do formulário como por exemplo . Bem então como o nome do meu Bean onde nele continha os atributos com os métodos acessores meu recebeu o mesmo nome do componente Seam a qual havia dado na classe RecuperarSenha.java como o nome dado aos atributos.

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:s="http://jboss.com/products/seam/taglib"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:a="http://richfaces.org/a4j"
	xmlns:rich="http://richfaces.org/rich"
	template="/layout/template.xhtml">

	<ui:define name="body"> <!-- id="usuario" -->
		<h:form  id="recuperarSenha" styleClass="edit">
		<rich:panel
				style="background-color: #{layoutManager.carregaConfiguracao('color.background.table.edit')};">
				<f:facet name="header">Nova Senha</f:facet>
							
				<s:decorate id="novaSenhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Nova senha</ui:define>
					<h:inputText id="novaSenha" required="true" size="20" maxlength="20"
						value="#{recuperarSenha.novaSenha}"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')};"/>
				</s:decorate>
				
				<s:decorate id="confirmanovaSenhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Confirma Senha</ui:define>
						<h:inputText id="confirmaNovaSenha" required="true" size="20" maxlength="20"
						value="#{recuperarSenha.confirmaNovaSenha}"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')};"/>
				</s:decorate>
				
				<!--<s:decorate id="_novaSenhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Nova senha</ui:define>
					<h:outputText id="novaSenha" 
						value="#{usuario.confirmaSenha}" rendered="#{recuperarSenha.novaSenha != null}"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')};"/>
				</s:decorate>
				
				<s:decorate id="_confirmaNovaSenhaField" template="/layout/edit.xhtml">
					<ui:define name="label">Confirma Senha</ui:define>
					<h:outputText id="novaSenha" 
						value="#{recuperarSenha.confirmaNovaSenha}" rendered="#{recuperarSenha.confirmaNovaSenha != null}"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')};"/>
				</s:decorate>-->
												
				<div style="clear: both"><span class="required">*</span>
				Campos obrigatórios</div>
			</rich:panel>
			<div class="actionButtons">
			<h:commandButton action="#{recuperarsenhaManager.salvarNovaSenha(recuperarSenha.novaSenha, recuperarSenha.confirmaNovaSenha)}" 
						value="Salvar" 						
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')}; "/>
			
			<s:button id="cancelar" value="Cancelar" propagation="end" view="/home.xhtml"
						style="color: #{layoutManager.carregaConfiguracao('color.text.table.edit')};
						font-size: #{layoutManager.carregaConfiguracao('size.text.input')}px;
						font-family: #{layoutManager.carregaConfiguracao('font.text.input')}; "/>
			</div>
			</h:form>
		</ui:define>
	</ui:composition>

E assim todos os objetos e a Action Listener poderia ser chamada corretamente, pois o Seam Phase Listener e o life cycle do JSF iriam instanciar esses objetos em tempo de execução corretamente sem gerar exception

3 - Injetar novamente um componente que já está injetado mata o escopo de contexto.

E por fim, no post anterior quando pedi ajuda a comunidade tinha um detalhe que só percebi depois de vários debug's na aplicação.

Eu estava injetando novamente na conversação um usuário que por natureza já tem um scopo de Sessão e por este motivo estava matando a conversação dos meu componentes descritos acima, pois ele já trazia do banco de dados a senha salva na hora do cadastro e anulava os dados inseridos no meu backing bean JSF.

Espero ter ajudado de alguma forma, e fico aberto para críticas construtivas, perguntas ou até mesmo indagações da comunidade porque acho que esse tema ainda pode ser discutido e de certa forma pode até surgir outra forma de solução.

Um abraço a todos e até a próxima

Criado 12 de janeiro de 2010
Respostas 0
Participantes 1