Criar filtro e/ou conta de usuário.

17/05/2010


Saudações equipe devmedia.com Este é meu segundo chamado, estou desenvolvendo um pequeno sistema de classificados onde o usuario pode se cadastrar e abrir uma conta, no estilo Mercado Livre. Já consigo cadatrar usuários e efetivar o login, levando o usuário para uma pagina que seria sua conta, igual no devmedia, onde os usuarios tem uma conta, porém em meu sistema, ainda nao consegui desenvolver o  filtro de usuário, tentei criar e adaptar para meu sistema baseado nas aula 15 e 16 do curso “Desenvolvendo uma aplicação completa com JPA” do Dyego Carmo, mas nao funciona bem pro meu caso, pois bloqueia tudo, ou seja, o usuário não tem permissão para navegar pelo site e ver os classificados, ao executar o projeto, o sistema carrega a pagina de login. preciso de um filtro que permita que o usuario possa navegar pelos anuncios sem se logar, mas que só permita acessar sua conta e as opções de sua conta ao se logar, ou seja, mesmo tendo o endereço direto no navegador, nao possa acessar sem login. Abaixo a minha pagina inicial.




Ao clicar em “Novo cadastro”,  carrega a pagina de cadastro de usuarios, mostrada abaixo E ao clicar em salvar,  a seguinte pagina é carregada

E se um usuario já cadastrado faz o login, tambem é levado pra essa pagina. O que preciso, caros mestres é desenvolver um filtro que vincule o id do usuário recém cadastrado ou do usuário que acabou de fazer login á sua conta, e que ao se logar mostre seu nome  em frente do label “BEM VINDO À SUA CONTA :” e a partir dai ele possa navegar em todas as opções que sua conta oferece,  e que proiba navegar nessas opções caso nao esteja logado. Acho que deu pra entender o que preciso desenvolver, é um filtro que todo site tem, inclusive o devmedia, onde posso navegar por varias paginas sem estar logado, mas que para cadastrar ou alterar algo em minha conta só estando logado.


Segue abaixo meu bean responsável pelo login package br.com.webtrade.faces.bean; import br.com.webtrade.dao.UsuarioDAO; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.validator.ValidatorException;   public class LoginFace {       private String userMail;     private String senha;     private UIInput userMailInput;     private UIInput senhaInput;
    public LoginFace() {     }     public String doLogin(){        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("logged",  "true");        return "paginaUsuario";     }     public void validateUsuario(FacesContext context, UIComponent component, Object value) throws ValidatorException {         boolean exists = new UsuarioDAO().isUsernameAndPasswordExists(userMailInput.getLocalValue().toString(), value.toString());         if(!exists){             FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "USUARIO/LOGIN INVALIDOS!","USUARIO/LOGIN INVALIDOS!");             throw new ValidatorException(message);         }     }     public String getSenha() {         return senha;     }     public void setSenha(String senha) {         this.senha = senha;     }     public String getUserMail() {         return userMail;     }     public void setUserMail(String userMail) {         this.userMail = userMail;     }     public UIInput getSenhaInput() {         return senhaInput;     }     public void setSenhaInput(UIInput senhaInput) {         this.senhaInput = senhaInput;     }     public UIInput getUserMailInput() {         return userMailInput;     }     public void setUserMailInput(UIInput userMailInput) {         this.userMailInput = userMailInput;     } }   E abaixo segue o filtro   package br.com.webtrade.filtro;  import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   public class filtroLogin implements Filter {     private static final boolean debug = true;
    private FilterConfig filterConfig = null;
    public filtroLogin() {     }           public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)                 throws IOException, ServletException {                                 HttpServletRequest req = (HttpServletRequest) request;    HttpServletResponse resp =  (HttpServletResponse) response;      Object logged = req.getSession().getAttribute("logged");    String urlRequest = req.getRequestURL().toString();
   chain.doFilter(request, response);    System.out.println("veja "+logged+" e acessando "+urlRequest);     }      public FilterConfig getFilterConfig() {                 return (this.filterConfig);     }
    public void setFilterConfig(FilterConfig filterConfig) {                 this.filterConfig = filterConfig;     }       public void destroy() {     }       public void init(FilterConfig filterConfig) {                 this.filterConfig = filterConfig;                 if (filterConfig != null) {                     if (debug) {                                log("filtroLogin:Initializing filter");                     }                 }     }     @Override     public String toString() {                 if (filterConfig == null) return ("filtroLogin()");                 StringBuffer sb = new StringBuffer("filtroLogin(");                 sb.append(filterConfig);                 sb.append(")");                 return (sb.toString());     }
    private void sendProcessingError(Throwable t, ServletResponse response) {                 String stackTrace = getStackTrace(t);                 if(stackTrace != null && !stackTrace.equals("")) {                     try {                                response.setContentType("text/html");                                PrintStream ps = new PrintStream(response.getOutputStream());                                PrintWriter pw = new PrintWriter(ps);                                pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n");                                               pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");                                pw.print(stackTrace);                                pw.print("</pre></body>\n</html>"); //NOI18N                                pw.close();                                ps.close();                                response.getOutputStream().close();                     }                     catch(Exception ex) {}                 }                 else {                     try {                                PrintStream ps = new PrintStream(response.getOutputStream());                                t.printStackTrace(ps);                                ps.close();                                response.getOutputStream().close();                     }                     catch(Exception ex) {}                 }     }     public static String getStackTrace(Throwable t) {                 String stackTrace = null;                 try {                     StringWriter sw = new StringWriter();                     PrintWriter pw = new PrintWriter(sw);                     t.printStackTrace(pw);                     pw.close();                     sw.close();                     stackTrace = sw.getBuffer().toString();                 }                 catch(Exception ex) {}                 return stackTrace;     }
    public void log(String msg) {                 filterConfig.getServletContext().log(msg);     } }
obrigado pela atenção, fico no aguardo de um contato.




Rodrigo Vieira

Rodrigo Vieira

Curtidas 0

Respostas

Henrique Weissmann

Henrique Weissmann

17/05/2010

Oi Rodrigo, neste caso, não sei se filtros seriam de fato a melhor solução, pois conforme seu sistema for evoluindo, mantê-los vai ir se tornando cada vez mais complicado. Tenho portanto uma alternativa mais interessante para você que resolve seus dois problemas. 1. Crie um managed bean que represente o seu usuário, e defina seu escopo como sendo de sessão. No momento em que o usuário efetuar login no sistema, preencha esta variável usando o objeto FacesContext. (no final deste post incluirei um exemplo de classe de fachada que facilita muito o trabalho com este objeto). 2. Com esta variável de sessão preenchida, incluir nas suas páginas elementos que só devam aparecer caso um usuário esteja logado é simples: basta adicionar o atributo rendered à sua tag relacionada, tal como no exemplo abaixo: No caso, o input text só será renderizado se o seu usuário estiver logado 3. Agora, com relação às páginas que o seu usuário poderá ou não ver. Minha sugestão é que nos seus managed beans que façam o redirecionamento você verifique a presença de um usuário logado e retorne um valor de acordo com o fato do usuário estar logado no seu sistema ou não. Suponha que você possua um managed bean chamado DadosPessois, que direcione seus usuários a uma daquelas páginas que expõem dados da conta. Normalmente há uma action implementada tal como no código abaixo: public String exporDadosPessoais() { if (haUsuarioLogado()) { // lógica de negócio return "exponha"; // no seu mapeamento, fará o redirecionamento correto } else { return null; // não é feito o redirecionamento } } Assim você poderá trabalhar caso a caso de acordo com o managed bean. Visto que normalmente um managed bean está relacionado a mais de uma página, você não terá tanto trabalho assim. É possível inclusive refatorar seu código para que este processo seja simplificado. Se alguém tentar acessar uma página diretamente, não obterá valor nenhum (muito provávelmente obterá uma mensagem de erro), pois como esta ainda não foi populada por um managed bean, não haverá nada para ser exposto também. Abaixo segue a classe de fachada que costumo usar para lidar com o objeto FacesContext. import javax.faces.application.FacesMessage; import javax.faces.context.*; import javax.servlet.http.*; public class FacadeWeb { /** Retorna o objeto request externo ao Faces */ public static synchronized HttpServletRequest getRequest() { FacesContext contextoFaces = FacesContext.getCurrentInstance(); if (contextoFaces == null || contextoFaces.getExternalContext() == null || contextoFaces.getExternalContext().getRequest() == null) return null; return (HttpServletRequest) contextoFaces.getExternalContext().getRequest(); } /** Exclui da sessão determinado bean */ public static synchronized void excluirAtributoSessao(String nomeVariavel) { getRequest().getSession().removeAttribute(nomeVariavel); } /** Define um atributo de sessão */ public static synchronized void setAtributoSessao(String atributo, Object valor) { getRequest().getSession().setAttribute(atributo, valor); } /** Define um atributo de requisição */ public static synchronized void setAtributoRequisicao(String atributo, Object valor) { getRequest().setAttribute(atributo, valor); } /** Retorna um atributo de sessão */ public static synchronized Object getAtributoSessao(String atributo) { return getRequest().getSession().getAttribute(atributo); } /** Retorna um atributo de requisição */ public static synchronized Object getAtributoRequisicao(String atributo) { return getRequest().getAttribute(atributo); } /** Construtor padrão */ public FacadeWeb() { } }
GOSTEI 0
Rodrigo Vieira

Rodrigo Vieira

17/05/2010


Caro Lobo, é o seguinte, vê se está no caminho certo o que eu fiz.

Dentro do meu UsuarioDAO eu criei este metodo.

public Integer isUsernameAndPasswordExists2(String userMail, String senha){         Integer IdUsr = null;                EntityManager em = JPAUtil.getInstance().getEntityManager();         Query qr = em.createQuery("select usr from Usuario usr where usr.email = ?1 and usr.senha = ?2");         qr.setParameter(1, userMail);         qr.setParameter(2, senha);         List<Usuario> rsusuario = new ArrayList<Usuario>();         rsusuario = qr.getResultList();         if (rsusuario.size() > 0){         if((rsusuario.get(0).getEmail().equals(userMail)) && (rsusuario.get(0).getSenha().equals(senha)))         {               IdUsr = rsusuario.get(0).getId_usuarios();         }else {               IdUsr = 0;         }         }         em.getTransaction().commit();         em.close();         return IdUsr;}
e no meu LoginFace está assim.

private Integer id_usuarios;private String mail;// getters e setters
public void validateUsuario(FacesContext context, UIComponent component, Object value) throws ValidatorException {        Integer exists = new UsuarioDAO().isUsernameAndPasswordExists2(userMailInput.getLocalValue().toString(), value.toString());        if(exists.equals(null)){        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "USUARIO/LOGIN INVALIDOS!","USUARIO/LOGIN INVALIDOS!");         throw new ValidatorException(message);         }else{         id_usuarios = exists;         mail = userMailInput.getLocalValue().toString();         System.out.println("codigo do usuário = "+exists);         System.out.println("email do usuário = "+mail);         }  }

OK, consigo pegar o id e o e-mail do usuário, o e-mail, que é o login do usuário, eu já estou conseguindo anexar na pagina do usuário quando ele a acessa, atravéz da tag

<h:outpuText id="mailUser" value="#{LoginFace.mail}"/>

até ai beleza, o que voce acha ?

Agora o que preciso é jogar o valor do id capturado na sessão dentro da entidade produtos, ou seja, um usuário pode cadastrar varios anuncios de produtos.

consigo mostrar na pagina de produtos o id do usuário

<h:outpuText id="idUser" value="#{LoginFace.id_usuarios}"/>

o que quero é pegar esse valor e joga-lo diretamente dentro da chave estrangeira id_usuarios na entidade produtos, resolvendo isso, mata 70% do meu problema.

outra coisa, vai precisar fazer um converter ?

Valeu. fico no aguardo.










 


GOSTEI 0
Henrique Weissmann

Henrique Weissmann

17/05/2010

Olá Rodrigo,

sim, você está indo na direção correta, porém gostaria de fazer algumas sugestões ok?

Sugestão número 1:
na sua classe UsuarioDAO ao invés de retornar um valor inteiro, retorne a instância de Usuario.
Duas razões para tal:
* Apenas um número não torna nítido o que exatamente está sendo retornado (pense em outro desenvolvedor trabalhando no seu código)
* A classe Usuario pelo que pude ver já possui todas as informações que você deseja expor na interface gráfica.

Sugestão número 2:
Defina um managed bean chamado usuario que seja do tipo "Usuario" com escopo de sessão e em seguida  implemente a interface java.io.Serializable na classe Usuario.
Assim você poderá pegar o resultado da função que retorna um usuário válido com base na senha e login e armazená-la na sessão evitando problemas ao variar de servidor de aplicações.
(Alguns servidores ou frameworks persistem os dados da sessão em disco. Se você não implementa a interface Serializable pode vir a enfrentar problemas).

O problema que você está tendo em expor o e-mail do usuário em suas páginas é resolvido com a sugestão número 2. A partir do momento em que o usuário está armazenado na sessão, tudo o que você precisará fazer para expor seus dados será referenciá-lo tal como no exemplo abaixo:

<f:outputText value="#{usuario.email}"/>

Bem mais interessante do que ficar tendo de fazer a consulta por e-mail repetidas vezes pelo managed bean, pois você só precisa buscar os dados uma vez (no momento em que inclui a sua instância de usuário na sessão).

Como jogar o valor do usuário como chave estrangeira nos pedidos: da mesma forma como expos os dados do e-mail. Basta obter o usuário armazenado na sessão (use a classe de fachada que te passei no post anterior) e em seguida atribui-la a cada pedido.
GOSTEI 0
POSTAR