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 acessorespackage 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.
e por fim meu Backing Bean JSF@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 ""; }<!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
<!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