E ae pessoal tranquilo?
Estou desenvolvendo uma aplicacao onde qdo o usuario faz o login, eu atualizo uma classe clsUsuario, que contem metodos get e set, e jogo essa classe na session. O problema é que qdo outro usuário se conecta ao sistema a session é atualizada com as caracteristica do usuario que logou, sendo assim, se na minha session contia as minhas informacoes, agora ela contem as informacoes do usuario que logou!!!
Alguem saberia o motivo?
Esse é o código do servlet que recebe as informacoes de um formulario. Li algo sobre SingleThreadModel mas nao funcionou. Nesse exemplo substitui a Usuario pela Geral, que tem a mesma estrutura, com get e set.
public class srvlConectar extends HttpServlet implements SingleThreadModel {
private String strUsuario, strSenha;
private int intIdioma;
private clsProfissional Profissional;
HttpSession httpSession;
private clsGeral2 Geral;
private clsUsuario Usuario;
private clsIdioma Idioma;
/**
* Metodo doPost - Recebe requisições POST do Browser.
*
* @param httpRequest - HttpServletRequest
* @param httpResponse - HttpServletResponse
*
* @since 30.11.2002
*
*/
public void doPost(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
throws ServletException, IOException {
//Recuperando o idioma setado pelo usuário
intIdioma = Integer.parseInt(httpRequest.getParameter("hdnIdioma"));
//Instanciando a classe clsIdioma
Idioma = new clsIdioma();
//Instacia a clsUsuario para setar as caracteristicas de usuario
//Usuario = new clsUsuario();
[b]Geral[/b] = new clsGeral2();
//armazena o numero do Idioma na clsUsuario
//Usuario.setIntIdioma(intIdioma);
[b]Geral.setIntIdioma(intIdioma);[/b]
//Instanciando um session que conterá a classe clsUsuario
httpSession = httpRequest.getSession();
//Atribuindo a classe clsUsuario a session
//httpSession.setAttribute("Usuario", Usuario);
httpSession.setAttribute("Geral", Geral);
//Testa se os parametros que contem a senha e o usuario nao sao vazios
if (!httpRequest.getParameter("ftxtUsuario").equals("") &&
!httpRequest.getParameter("fpassSenha").equals("")) {
//Recupera o parametro que contem a senha do usuario
strSenha = httpRequest.getParameter("fpassSenha");
//Recupera o parametro que comtem o nome de usuario
strUsuario = httpRequest.getParameter("ftxtUsuario");
//Chama o metodo conecta()
conecta(httpRequest, httpResponse, httpSession);
}
else
//Chama o metodo redireciona()
redireciona(httpRequest, httpResponse, "/scp/jsp/jspConectar.jsp?strMensagem=" +Idioma.buscaMensagem(7,Usuario.getIntIdioma()));
}
/**
* Metodo doGet - Recebe requisições GET do Browser.
*
* @param httpRequest - HttpServletRequest
* @param httpResponse - HttpServletResponse
*
* @since 30.11.2002
*
*/
public void doGet(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
throws ServletException, IOException {
redireciona(httpRequest, httpResponse, "/scp/jsp/jspConectar.jsp?idioma=1");
}
/**
* Metodo Conecta - Responsavel por validar o usuario e carregar as variaveis de ambiente do usuario
*
@param httpRequest - HttpServletRequest
* @param httpResponse - HttpServletResponse
*
* @since 30.11.2002
*
*/
public void conecta(HttpServletRequest httpRequest, HttpServletResponse httpResponse, HttpSession phttpSession) {
Profissional = new clsProfissional();
try {
ResultSet rsUsuario = Profissional.retornaUsuario(strUsuario.trim());
if (rsUsuario.next()) {
//Testa se a senha recuperada é igual a senha contida na base de dados
if (rsUsuario.getString(Profissional.getTFName("Senha")).equals(trataString(strSenha))) {
//armazena a Chave do Profissional Logado
//Usuario.setIntChProfLogado(rsUsuario.getInt(Profissional.getTFName("ChProf")));
[b]Geral.setIntChProfLogado[/b](rsUsuario.getInt(Profissional.getTFName("ChProf")));
//armazena a Chave do Grupo a que pertence o Profissional Logado
//Usuario.setIntChGruProfLogado(rsUsuario.getInt(Profissional.getTFName("ChGru")));
[b]Geral.setIntChGruProfLogado[/b](rsUsuario.getInt(Profissional.getTFName("ChGru")));
//armazena o Nome de Usuário do Profissional Logado
//Usuario.setStrProfLogado(rsUsuario.getString(Profissional.getTFName("User")));
[b]Geral.setStrProfLogado[/b](rsUsuario.getString(Profissional.getTFName("User")));
//Atribuindo a classe clsUsuario a session
//phttpSession.setAttribute("Usuario", Usuario);
[b]phttpSession.setAttribute("Geral", Geral);[/b]
try {
//Chamando o Servlet srvlMontaMenu
new srvlMontaMenu().doPost(httpRequest,httpResponse, "menuGeral");
System.out.println("session srvlConectar : "+Geral);
//Carregando o jsp com o menu de acordo com o perfil do usuario logado
redireciona(httpRequest, httpResponse, "/scp/jsp/jspIndexSCP.jsp");
}
catch (Exception e) {
//Erro ao chamar o srvlMontaMenu
System.out.println("Erro ao chamar o srvMontaMenu : "+e);
}
}
else
//Senha invalida
redireciona(httpRequest, httpResponse, "/scp/jsp/jspConectar.jsp?strMensagem="+Idioma.buscaMensagem(13,intIdioma));
}
else
//Usuario invalido
redireciona(httpRequest, httpResponse, "/scp/jsp/jspConectar.jsp?strMensagem="+Idioma.buscaMensagem(12,intIdioma));
//Fechando o ResultSet rsUsuario
rsUsuario.close();
//Fechando o PreparedStatement da classe clsProfissional
Profissional.pstmtProfissional.close();
}
catch (SQLException excBanco) {
redireciona(httpRequest, httpResponse, "/scp/jsp/jspConectar.jsp?strMensagem=Erro no srvlConectar - conecta()");
}
}
Tive um problema semelhante utilizando JSP!! Eu gravava uma query na sessão do usuário e quando outro acessava ele pegava a query do outro usuário.
O que deve estar acontecendo é o seguinte:
Quando gravamos um objeto na session do usuário, o que é realmente gravado é a sua posição de memória e não uma cópia do objeto. Portanto se vc instancia apenas um objeto clsUsuario para atender várias solicitações o mesmo fica compartilhado e quando um usuário altera esse valor, ele altera o valor que os outros usuários vêem também pois se trata do mesmo objeto (mesma posição de memória para sessões diferentes). Eu resolvi o problema criando um novo objeto para cada usuário. Eu verifico primeiro se ele já tem setado na sessão uma query. Se não tiver eu dou um new query e problema resolvido! =)
Notei que você colocou o objeto HttpSession como uma variável membro da classe do Servlet, se você declarar a mesma dentro do método doGet() ou doPost() não terá mais problemas, acredito.
Isto acontece porque o container cria uma sessão para cada usuário, mas a variável em que você está armazenando estas sessões é compartilhada entre mais de um usuário, ou seja, quando um novo usuário se loga, ele sobrepõe as informações já existentes! Existe um artigo sobre isso aqui no guj (Thread Safety com Servlets).
Espero ter sido claro, qualquer dúvida, estamos ai!
Pessoal, legal essa ajuda, acho que podemos achar um caminho. Pra isso vou detalhar melhor a situaçao.
Estou portando uma aplicação local para a web, mas o problema que a estrutura dessa aplicação não foi totalmente pensada para a web. A aplicação tem a camada de apresentação, a camada de negocio e a camada de banco de dados, até ae beleza. Nessa aplicação local existe um clsGeral, que é carregada com todas as informação do usuário no momento em que este se loga no sistema. Como trata-se de uma alpicacao local existe uma clsGeral para cada estacao. Todas as outras classes extends dessa clsGeral, acessando variaveis dentro da clsGeral, por exemplo, grupo do usuário, idioma, id, user, etc. Para nao mexer nessa estrutura na web eu imaginei que instanciando uma clsGeral, alimentando-a com as informacoes do usuario e atribuindo isso na sessao, eu imaginava que qdo estanciasse qualquer cls que extendesse da cslGeral, esta conseguiria enxergar o conteudo da clsGeral contida na sessao, mas isso nao acontece.
Bom acho que isso da pra ter uma noção do que esta acontecendo.
Vamos debater a situação, buscando um solução pro caso.
Sem mais, valeu.
Thiago
Desenvolvedor Junior - Java
Universidade Estadual Paulista - Unesp
Eu concordo com o Carlos, o HttpSession deve ser criado dentro do metodo e nao como membro da classe. Voce ja tentou alterar isso para ver se o problema é solucionado?
O problema não é que com a session, e sim com a clsGeral. Qdo outro usuario conecta no sistema todas as sessions passa a ter o conteudo do ultimo usuario, declarei a session no doPost e doGet, mas nada, como a sessao contem um objeto do tipo clsGeral, qdo este é atualizado todos sao alterados. E acho que o servlet nao instancia uma clsGeral para cada conexao. As cls acessam as propriedade dos atributos, nao existem get e set na clsGeral, por exemplo, clsGeral.intChProfLogado = 1. Uma maneira que eu pensei seria duplicar os construtores de todas as cls, ou seja, qdo instanciasse na web passaria os parametros contidos no objeto de sessao do usuario, e qdo fosse local buscaria da clsGeral, pelo extends. Seila foi a luz que veio em minha cabeça.
Entao coloca os objetos dentro dos doXXX ao inves de membros da classe, pois se cada usuario eh para ter seu proprio objeto, entao nao ha razao para fazer como foi feito.
[quote=“Paulo Silveira”]jsp_dev, ja tinha falado isso ai, e pelo que vi no codigo, nao eh isso
pode ver que ele isntancia um para cada request[/quote]
Olá!! Eu percebi isso também mas acontece que ele instacia uma variável membro portanto ele está compartilhada… acho que uma solução é a que o Carlos disse e que o Paulo confirmou e a outra é declarar a clsGeral dentro dos métodos doPost e doGet…