Habilitar uma vez por sessão (synchronized)

22 respostas
jason_bourne

Pessoal,

Como faço para deixar que o usuário se logue uma vez por sessão em uma aplicação web? Sei que tenho que usar o synchronized, mas não sei como. Segue meu servlet de autenticação e gravação no session:

public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException,IOException{

  String userId = req.getParameter("userId");
  String password = req.getParameter("password");

            try {
            Class.forName("org.postgresql.Driver");
            } catch(java.lang.ClassNotFoundException e) {
            System.err.print("ClassNotFoundException: ");
            System.err.println(e.getMessage());
            }

        try {
 
            Connection con = null;
            ResultSet rs = null;
            con = DriverManager.getConnection("jdbc:postgresql://localhost/sistema", "usuario", "senha");
            
            /* pega dados do usuário */
            String sql = "SELECT id,login,nome,senha,level,ativo FROM usuarios WHERE login LIKE '"+ userId +"' AND senha LIKE '"+ password +"' AND ativo='1'";

            Statement s = con.createStatement();
            
            rs = s.executeQuery(sql);

                   
            
         if (rs.next()) {
            
         HttpSession userSession = req.getSession(true);
                                     
         try{

          String nivel = rs.getString("level");
          String id_usuario = rs.getString("id");
          String nome_usuario = rs.getString("nome");
          int ativo = rs.getInt("ativo");

          userSession.putValue("nome_usuario", nome_usuario);
          userSession.putValue("nivel", nivel);
          userSession.putValue("id_usuario", id_usuario);
          userSession.putValue("usuario", userId);
          userSession.putValue("userName", "1");

         }catch(SQLException e){
           System.out.println(e);
         }           
        
         RequestDispatcher rd = getServletContext().getRequestDispatcher("/home.jsp");
         RequestDispatcher rdinativo = getServletContext().getRequestDispatcher("/erroInativo.jsp");

         if (rd != null){
	  rd.forward(req,res);
         }              
                
         }else{
      
         RequestDispatcher rd2 = getServletContext().getRequestDispatcher("/erroLogin.jsp");
    
         rd2.forward(req,res);
         }
         
  
         rs.close();
         s.close();
         con.close();

        } catch (SQLException e){
            e.printStackTrace();           
        }

Ou seja, eu quero que se o usuário tentar logar em outro micro e o session ainda estiver ativo, ele não deixe.

22 Respostas

Mauricio_Linhares

Primeiro você pode criar uma coleção de usuários logados no sistema (e coloca ela no contexto da aplicação), toda vez que algum usuário se logar, você vê se ele já está logado procurando na coleção, se ele estiver, você barra, se ele não estiver, você loga e coloca ele na coleção.

Quando ele pedir pra fazer logoff, você retira ele da coleção.

Mas pode ser que ele saia sem fazer logoff, então você deve usar um HttpSessionListener pra quando uma sessão for “detonada” o listener ver se tem algum usuário nela e retirar ele da coleção.

Z

Eu diria que com certeza todos (bem, nem tanto… mas uns 99%) os usuários sairão do sistema sem clicar em logoff/logout.

Como já foi comentado aqui no fórum, o link de logoff só faz ocupar espaço. :smiley:

jason_bourne

Maurício Linhares:
Primeiro você pode criar uma coleção de usuários logados no sistema (e coloca ela no contexto da aplicação), toda vez que algum usuário se logar, você vê se ele já está logado procurando na coleção, se ele estiver, você barra, se ele não estiver, você loga e coloca ele na coleção.

Quando ele pedir pra fazer logoff, você retira ele da coleção.

Mas pode ser que ele saia sem fazer logoff, então você deve usar um HttpSessionListener pra quando uma sessão for “detonada” o listener ver se tem algum usuário nela e retirar ele da coleção.

Desculpe, mas como faço para criar essa coleção de usuários logados e colocar no contexto?

L

Também quer sabe isto.

Valeu.

_fs

http://websphere.sys-con.com/read/43208.htm
http://www.phptr.com/articles/article.asp?p=26118&seqNum=3

jason_bourne

Eu tenho que colocar todos os usuários dentro do contexto? pq se for assim, para mim é inviavel já que os usuários eu pego do banco de dados.

L

Lipe sempre o Lipe !!!.

Valeu mestre.
Era isto mesmo.

Um abração.

F

Tu pega do banco, mas coloca os dados do usuario em algum Objeto certo? Tipo Usuario ou Login. Se voce faz isso coloque este Objeto na sessao. Agora se voce nao faz isso, podia explicar como faz?

]['s

jason_bourne

Tu pega do banco, mas coloca os dados do usuario em algum Objeto certo? Tipo Usuario ou Login. Se voce faz isso coloque este Objeto na sessao. Agora se voce nao faz isso, podia explicar como faz?

]['s

O código que eu uso esta logo acima. Eu pego por post o usuário e senha, verifico se existe no banco, e se existir eu gravo o session. A única coisa que quero é não deixar que o usuário logue mais de uma vez se o session ainda estiver ativo.

Me disseram que tenho que usar o método synchronized, mas mesmo procurando no google não encontrei nada relativo a isso.

F

Tu pega do banco, mas coloca os dados do usuario em algum Objeto certo? Tipo Usuario ou Login. Se voce faz isso coloque este Objeto na sessao. Agora se voce nao faz isso, podia explicar como faz?

]['s

O código que eu uso esta logo acima. Eu pego por post o usuário e senha, verifico se existe no banco, e se existir eu gravo o session. A única coisa que quero é não deixar que o usuário logue mais de uma vez se o session ainda estiver ativo.

Me disseram que tenho que usar o método synchronized, mas mesmo procurando no google não encontrei nada relativo a isso.

Diz uma outra coisa. COmo é o tratamento que tu quer dar se o usuario tentar logar de outro browse. Tu quer reaproveitar o login? Ou seja nao pedir para ele logar denovo?

]['s

jason_bourne

Se ele tentar com outro browser, quero dar uma mensagem de erro dizendo que ainda existe uma conexão ativa com este login.

F

Entao tu vai ter que mudar um pouco teu servlet e fazer conforme falado nos outros posts ai em cima.

Crie um objeto que armazene os dados do usuario logado e coloque este no contexto corme falado ja. Ai sempre que um novo usuario tentar logar tu verifica se existe algum objeto ja no contexto que tenha as mesmas informacoes do usuario que ta tentando logar.

]['s

jason_bourne

Entao tu vai ter que mudar um pouco teu servlet e fazer conforme falado nos outros posts ai em cima.

Crie um objeto que armazene os dados do usuario logado e coloque este no contexto corme falado ja. Ai sempre que um novo usuario tentar logar tu verifica se existe algum objeto ja no contexto que tenha as mesmas informacoes do usuario que ta tentando logar.

]['s

Acabei de fazer isso. Setei o context com o id do usuario e coloquei um if para verificar se o context exite com o id do usuario, se não existir ele deixa logar. Só que quando eu vou testar, ele nem loga, aparece essa msg:

java.lang.NullPointerException
	Login.doPost(Login.java:95)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:362)

note

o código é esse:

//verifica se esta no contexto
          ServletContext contexto1 = getServletContext();
          String verContexto = (String)(contexto1.getAttribute("usuarioC"));  
          
          if(!(verContexto.equals(id_usuario))){
          ServletContext contexto = getServletContext();
          contexto.setAttribute("usuarioC", id_usuario); 

          userSession.putValue("nome_usuario", nome_usuario);
          userSession.putValue("nivel", nivel);
          userSession.putValue("id_usuario", id_usuario);
          userSession.putValue("usuario", userId);
          userSession.putValue("userName", "1");
          userSession.putValue("teste", verContexto);
          }

Obs: eu fiz um teste, e ele esta pegando corretamente o id no contexto e tb o id do banco.

F

O que tem na linha 95 da classe Login.java

:?:

jason_bourne
if(!(verContexto.equals(id_usuario))){
Mauricio_Linhares

Então teste primeiro se “verContexto” é nulo, porque se for nulo é porque não tem nenhum usuário ali.

jason_bourne

Eu até consigo gravar o contexto, mas depois não consigo recupera-lo para verificar se ele já foi gravado anteriormente. Segue:

1          int verContexto = 0,verContexto2=0;
2         ServletContext contexto1 = getServletContext();
3          try{
4              Integer objectInteger = (Integer)(contexto1.getAttribute("usuarioC"));
5              verContexto2 = objectInteger.intValue();
6
7          }catch(Exception e){
8              System.out.println(e.getMessage());
9          }

Ele não pega o valor do contexto na linha 4. Alguem sabe o motivo disso?

jason_bourne

Consegui criar o contexto e verificar se ele ta setado! :smiley:

Mas como faço para destrui-lo quando o usuário sair ou clicar no logout?

Pq eu pensei em colocar um body unload e quando o usuario sair do sistema, ele chama um popup com um jsp contendo o metodo contexto.removeAttribute(nome) mas isso fica um tanto inviavel já que existe bloqueadores do popups e browsers que broqueiam por default qualquer popup chamado pelo unload, como é o caso do firefox.

Alguem sabe como resolver isso?

jason_bourne

Alguem sabe como verificar se o browser foi fechado ? :?

Mauricio_Linhares

Como eu disse lá nos primeiros posts, você retira o usuário do contexto quando ele clicar lá no link de logout e coloca um HttpSessionListener lá no seu web.xml, e quando a sessão for destruída você retira o usuário.

E não dá pra saber que o browser foi fechado não.

Dê uma olhada nisso aqui:

http://www.stardeveloper.com/articles/display.html?article=[telefone removido]&page=1

jason_bourne

Maurício Linhares:
Como eu disse lá nos primeiros posts, você retira o usuário do contexto quando ele clicar lá no link de logout e coloca um HttpSessionListener lá no seu web.xml, e quando a sessão for destruída você retira o usuário.

E não dá pra saber que o browser foi fechado não.

Dê uma olhada nisso aqui:

http://www.stardeveloper.com/articles/display.html?article=[telefone removido]&page=1

Consegui fazer com que eu sabia se o usuário fechou o browser. É bem simples, é só criar um frame invisivel e no frameset vc coloca

<frameset cols="100%,0%" framespacing='0' frameborder='0' border=0  onunload="parent.lateral.location.href='Logout.jsp'">

Esse Logout.jsp seria a página contendo o removedor do contexto. :wink:

Espero ter ajudado alguem que tenha o mesmo problema.

Mauricio_Linhares

Cara, isso é uma gambiarra terrível, e se o browser do cara não tem ou está com o JavaScript desabilitado?

Coloque o listener pra sessão e pronto, facilite a sua vida.

Criado 22 de junho de 2005
Ultima resposta 23 de jun. de 2005
Respostas 22
Participantes 6