Habilitar uma vez por sessão (synchronized)

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.

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.

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:

[quote=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.[/quote]

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

Também quer sabe isto.

Valeu.

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

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.

Lipe sempre o Lipe !!!.

Valeu mestre.
Era isto mesmo.

Um abração.

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

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[/quote]

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.

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[/quote]

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.[/quote]

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

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

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

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[/quote]

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.

O que tem na linha 95 da classe Login.java

:?:

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

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

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?

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?

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