Fórum Dúvida sobre login com JSF #387993

06/10/2010

0

Estou desenvolvendo meu trabalho de conclusão de curso e estou tendo dificuldades em implementar a funcionalidade de login com JSF. Além do login tenho que gerar sessões pois todas as páginas devem ser acessadas por pessoas autorizadas.

Vi a vídeo aula número 15 do curso desenvolvendo uma aplicação com JPA ministrada pelo Dyego Carmo e fiz algumas adaptações para meu problema, mais ao executar a aplicação aparece a seguinte mensagem de erro:

"java.lang.IllegalArgumentException: org.hibernate.QueryException: JPA-style positional param was not an integral ordinal "

Estrutura criada. Gerei uma unidade de persistencia chamada SISMOTPU2. Foi gerada um loginFace e uma classe Chamada TesteLoginDAO que implementa o metodo public boolean isUsernameAndPasswordExists(String username, String password){ }

TesteLoginDAO: http://paste-it.net/public/d32e7cf/
LoginFace: http://paste-it.net/public/p1b57aa/

Dentro deste metodo gerei uma instancia do EntityManagerFactory e do entityManager, a query de consulta foi personalizada e realiza uma pesquisa junto a tabela funcionario, abaixo destaco a query

em.createQuery("select nomeFuncionario from Funcionario f where f.id = ?1"+
"and f.senha = ?2");

Ao executar o debug da aplicação o único valor que consigo visualizar não nulo e o campo password o
campo username sempre vem nulo

Alem das classes foi gerada a tela de login

areaLogin.jsp : http://paste-it.net/public/n44acea/

no faces config configurei para caso tenha sucesso no login ele direcionar para a seguinte pagina
 principal.jsp na raiz do diretorio web.

Estou utilizando o hibernate em minha aplicação, caso eu faça esta funcionalidade com JPA, estarei
 rompendo algum padrão de projeto?

O que devo fazer para solucionar este problema?

Segue abaixo link para acessar o codigo do projeto

src: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/classes/src_4.rar
web: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/web/web_4.rar
imagens: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/telas/telaLogin.rar

Desde já agradeço.

Marcos Sousa

Marcos Sousa

Responder

Posts

06/10/2010

Marcos Sousa

Esqueci de informar o back up do banco de dados. Segue abaixo link do back up do banco

http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/script_banco/db_sismot 20101006 0015.rar

Os dados para efetuar login são
Matricula : 1
Senha: 123

Há somente um funcionário cadastrado.


Responder

Gostei + 0

06/10/2010

Henrique Weissmann

Olá, o problema está no índice dos parâmetros passados na sua classe TesteLoginDAO. No caso do JPA, os parâmetros são iniciados com índice 0. Sendo assim, ao invés de passar os parametros nas ordens 1 e 2, tente passá-los na ordem 0 e 1.
Responder

Gostei + 0

06/10/2010

Marcos Sousa

Boa tarde Henrique. Fiz a alteração que voce me sugeriu e realizei um debug sobre a aplicação mais ele continua retornando a seguinte mensagem de erro junto a tela de login.

"java.lang.IllegalArgumentException: org.hibernate.QueryException: JPA-style positional param was not an integral ordinal "

na classe LoginFace coloquei break points nas seguintes linhas.

 public void validateLogin(FacesContext context, UIComponent component, Object value) throws ValidatorException {

        System.out.print("The username "+username + " password "+password +" value to string "+ value.toString());
        // breakpoint System.out.print("The usernameInput "+usernameInput.getLocalValue().toString() + " passwordInput "+passwordInput.getSubmittedValue() +" value to string "+ value.toString());
      //BreakPoint  boolean exists = new TesteLoginDAO().isUsernameAndPasswordExists(username, value.toString());
        if(!exists){
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "MATRICULA/SENHA INVALIDOS", "MATRICULA/SENHA INVALIDOS");
            throw new ValidatorException(message);
        }
    }
}

Ao visualizar os breakpoints deste metodo o username fica null e o unico valor que e passado e o value.toString() que carrega a senha.
O usernameInput e o passwordInput não consegui visualizar os valores para eles.

acesso ao loginFace: http://paste-it.net/public/rc11940/

no método isUsernameAndPasswordExists fiz as alterações que voce me solicitou que era de inicializar os parametros a partir do 0.

Envio a classe com para analise: http://paste-it.net/public/x292ff8/

O que devo fazer para corrigir está falha? Desde já agradeço.


Responder

Gostei + 0

13/10/2010

Henrique Weissmann

Marcos,


Testando seu código no meu editor, observei um detalhe interessante.
Primeiro, veja o seu código original:

public boolean isUsernameAndPasswordExists(String username, String password){ boolean exists = false; EntityManagerFactory emf = Persistence.createEntityManagerFactory("sismotPU2"); EntityManager em = emf.createEntityManager(); //breakpoint em.getTransaction().begin(); //breakpoint //Alterei a query para ?0 e ?1 inseri um break point nesta linha Query qr = em.createQuery("select nomeFuncionario from Funcionario f where f.id = ?0"+ "and f.senha = ?1"); qr.setParameter(0, username); //breakpoint linha não executada qr.setParameter(1, password); try { exists = qr.getSingleResult() != null; //breakpoint linha não executada } catch (Exception e) { exists = false; } em.getTransaction().commit(); em.close(); return exists; }

agora, repare neste trecho:

Query qr = em.createQuery("select nomeFuncionario from Funcionario f where f.id = ?0"+ "and f.senha = ?1");

O que ocorre: o problema está na concatenação da String.
O resultado desta concatenação será

"select nomeFuncionario from Funcionario f where f.id = ?0and f.senha = ?1"

Coloque um espaço antes da primeira concatenação que o problema deverá ser resolvido.

Responder

Gostei + 0

14/10/2010

Marcos Sousa

Henrique adicionei o espaço na linha da query conforme sua orientação.

Query qr = em.createQuery("select nomeFuncionario from Funcionario f where f.id = ?0"+
                 " and f.senha = ?1");

Inseri breakpoints nas linhas e executei minha aplicação em modo debug, mais quando clico no botão Login ele não inicia o debug e me retorna o seguinte erro "
javax.servlet.ServletException: Target Unreachable, 'funcionario' returned null"

O que devo fazer para corrigir está falha.

Segue abaixo link para acesso aos codigos da aplicação.

source: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/classes/srcLoginrar.rar
paginas web: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/web/webLogin.rar

links para acesso ao
arealogin.jsp: http://paste-it.net/public/ee14d22/
FuncionarioBean: http://paste-it.net/public/lb51595/
TesteLoginDAO: http://paste-it.net/public/t3ec2f3/
persistence.xml: http://paste-it.net/public/x8f7c29/

desde já agradeço.
Responder

Gostei + 0

14/10/2010

Henrique Weissmann

Marcos, tenho algumas observações para o seu código. Com relação ao managed bean FuncionarioBean. Não é preciso fazer o binding entre os campos do seu formulário e os componentes diretos da classe. Você poderia fazer algo assim: por exemplo, em que apenas aponte para a propriedade login desta classe. Com relação ao método chamado no bean, o doLogin, é estranho você obter este erro, porque seu método não tem como retornar um valor nulo, visto que, pelo que pude ler no seu texto, ele apenas adiciona a variável logged na sessão com o valor true. O código que você está executando está realmente no formulário de login que você me passou neste link? http://paste-it.net/public/ee14d22/
Responder

Gostei + 0

15/10/2010

Marcos Sousa

Boa noite Henrique. Descobri o que estava gerando este problema no formulario areaLogin.jsp. Dentro de um <h:form> eu tinha dois commandButton
<h:commandButton value="Logar" action="#{funcionarioBean.efetuarLogin}" /><h:commandButton value="Home" action="#{funcionarioBean.home}" />Retirei os binding's do formularios e criei uma classe chamada FuncionarioDAOImpl onde tenho o metodo consultarLoginESenha
http://paste-it.net/public/b770744/

ao chamar a action do botão logar ele executa o metodo efetuarLogin de minha classe FuncionarioBean
http://paste-it.net/public/ceea679/AreaLogin.jsp: http://paste-it.net/public/p643a6c/

Agora ele esta fazendo o login, minha dúvida agora e a seguinte testei o metodo validateLogin da classe FuncionarioBean mais ele não funcionou como deveria me retornando a mensagem de usuario/senha invalidos. Com este erro ele me retorna um nullPointerException

como corrigo este problema?

Segue codigo fonte para analise
Responder

Gostei + 0

15/10/2010

Marcos Sousa

Havia esquecido de disponibilizar os codigos fontes do projeto. Seguem abaixo link para acesso

Web: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/web/webLogin2.rar
src: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/classes/srcLogin2.rar

Desde já agradeço.
Responder

Gostei + 0

17/10/2010

Henrique Weissmann

Marcos, com base na sua classe FuncionarioBean, há duas possibilidades para o erro NullPointerException.
No caso, tratam-se dos atributos testeDAO e funcionario. Observei que no seu código fonte, você declara estas variáveis já as definindo como novas instâncias de suas respectivas classes, no entanto, há também dois métodos do tipo set que as definem. Verifique os seguintes pontos:
Você está passando o valor null para algum destes setters?
Dica para evitar um NullPointerException: nos seus métodos, sempre verifique os valores das variáveis antes de acessá-las. Assim você pode detectar a presença de um atributo nulo antes que uma excessão seja disparada.
Outro ponto a ser verificado. Será que o erro não está ocorrendo dentro de TesteLoginDAO?
Dica: verifique o seu teste unitário ou o processo que leva à execução de suas classes. Muitas vezes podemos estar criando classes que, acidentalmente, só funcionem após a execução de um número pré-determinado de passos e que, em outro contexto, por não estarem prontas, gerem estes chatos erros do tipo NullPointerException.
Responder

Gostei + 0

19/10/2010

Marcos Sousa

Boa tarde Henrique, o problema sobre o nullPointerException foi gerado por este fator que voce me falou. Agora meu problema e garantir acesso as páginas da aplicação após a realização do login.
Tenho dentro da página welcomeJSF.jsp uma chamada a página de login.
<jsp:forward page="index.jsp"></jsp:forward>

Apos realizar o login nesta página sou direcionado para a pagina localizada em sismot/faces/principal.jsp, quero criar uma sessão é impedir o acesso direto a está página as pessoas que não efetuarem o login na aplicação. voce pode me demonstrar um exemplo para implementar isso?



Desde já agradeço.

Segue abaixo link das paginas:

index: http://paste-it.net/public/n1c1b42/
principal: http://paste-it.net/public/i0a82c0/

Responder

Gostei + 0

19/10/2010

Henrique Weissmann

Oi Marcos,
Neste caso, você precisa implementar um filtro. A plataforma Java EE nos fornece este recurso, que funciona da seguinte forma: você cria uma classe que implemente a interface javax.servlet.Filter e em seguida as configurações desta classe no arquivo web.xml da sua aplicação.
O filtro intercepta todas as chamadas ao seu servidor e em seguida faz os redirecionamentos caso necessário. Ele inclusive tem acesso à sessão do usuário. No seu caso, vai ser simples: caso a variável logado não esteja presente, ele fará o redirecionamento para alguma outra página de sua escolha.

O melhor exemplo que conheço do uso desta técnica é este tutorial presente no GUJ: http://www.guj.com.br/article.show.logic?id=11

Responder

Gostei + 0

26/10/2010

Devmedia

Marcos, a resposta do consultor tirou suas duvidas? Podemos encerrar o chamado?
Responder

Gostei + 0

26/10/2010

Devmedia

Marcos, a resposta do consultor tirou suas duvidas? Podemos encerrar o chamado?
Responder

Gostei + 0

26/10/2010

Marcos Sousa

Peço que aguarde até hoje para que eu possa implementar o exemplo que o Henrique me passou. Não tive tempo para estudar o tutorial.

Desde já agradeço.
Responder

Gostei + 0

26/10/2010

Marcos Sousa

Criei um pacote em minha aplicação chamado filtro e dentro dele implementei o FilterTime conforme exemplo do guj: http://paste-it.net/public/bc4ddb0/

Em seguida configuerei meu Xml da seguinte forma:

 <filter>
        <filter-name>timerFilter</filter-name>
        <filter-class>filtro.TimerFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>timerFilter</filter-name>
        <url-pattern>/faces/*</url-pattern>
    </filter-mapping>

E o navegador me retornou um erro 503. Alterei a configuração do filtro para a seguinte:

<filter>
        <filter-name>timerFilter</filter-name>
        <filter-class>filtro.TimerFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>timerFilter</filter-name>
        <url-pattern>/sismot/*</url-pattern>
    </filter-mapping>

E o erro foi o mesmo. O que devo fazer para resolver este problema. Estes metodos devem ser implementados no meu Bean responsavel por efetuar o login que e o FuncionarioBean?

xml: http://paste-it.net/public/v7e5b3b/
erroFiltro: http://paste-it.net/public/nea777f/
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar