Olá pessoal
Estou passando por um problema em minha aplicação Web Servlet/JSP
Tenho uma Servlet que recebe as requisições e repassa através de reflexão para as outras Servlets
Porém quando há 2 ou mais requisições ao mesmo tempo a HttpSession recebe o mesmo endereçamento de memoria, em Threads diferentes, ocasionando diversos problemas e inconsistências.
O Servlet despachante é esse:
ServletController.java
public class ServletController extends HttpServlet {
protected String paginaRetorno = "inicio.jsp";
protected Session sessaoHBN;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession sessaoHTTP;
protected synchronized void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.request = request;
this.response = response;
String acao = request.getParameter("acao");
try {
sessaoHTTP = request.getSession();
sessaoHBN = HibernateUtil.openSession();
Integer codEmpresa = (Integer) sessaoHTTP.getAttribute("codEmpresa");
if ((codEmpresa != null) || "efetuarLogin".equals(acao) || "cadastrarEmpresa".equals(acao)) {
Class clazz = this.getClass();
Method[] metodos = clazz.getMethods();
for (Method metodo : metodos) {
if (metodo.getName().equals(acao)) {
metodo.invoke(this, null);
}
}
} else {
this.setPaginaRetorno("login.jsp");
}
RequestDispatcher dispatcher = request.getRequestDispatcher(this.getPaginaRetorno());
dispatcher.forward(request, response);
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeCurrentSession();
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP
* <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP
* <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
/**
* @return the paginaRetorno
*/
public String getPaginaRetorno() {
return paginaRetorno;
}
/**
* @param paginaRetorno the paginaRetorno to set
*/
public void setPaginaRetorno(String paginaRetorno) {
this.paginaRetorno = paginaRetorno;
}
}
Necessito de uma ajuda para resolver esse problema, pois já verifiquei diversas possibilidades e não consegui encontrar uma solução
Efetuei também diversas pesquisas porém sem sucesso.
Gostaria de agradecer de antemão a atenção.
Saudações,
Anderson Souza
Tenta chamar o invoke dessa forma:
metodo.invoke(clazz.newInstance(), null)
[quote=danilovteodoro]Tenta chamar o invoke dessa forma:
metodo.invoke(clazz.newInstance(), null)
[/quote]
Obrigado pela atenção Danilo, porem não funcionou.
O valor do atributo sessaoHTTP está sendo substituído pelo o da requisição seguinte.
Saliento que esse problema só acontece quando 2 ou mais requisições são efetuadas simultaneamente.
Acho que isso acontece pq vc coloca toda a implementação da logica no servlet, você pode criar uma classe service para executar a logica por exemplo:
Classe Servce:
public class ServletServce {
protected String paginaRetorno = "inicio.jsp";
protected Session sessaoHBN;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession sessaoHTTP;
public void execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.request = request;
this.response = response;
String acao = request.getParameter("acao");
try {
sessaoHTTP = request.getSession();
sessaoHBN = HibernateUtil.openSession();
Integer codEmpresa = (Integer) sessaoHTTP.getAttribute("codEmpresa");
if ((codEmpresa != null) || "efetuarLogin".equals(acao) || "cadastrarEmpresa".equals(acao)) {
Class clazz = this.getClass();
Method[] metodos = clazz.getMethods();
for (Method metodo : metodos) {
if (metodo.getName().equals(acao)) {
metodo.invoke(this, null);
}
}
} else {
this.setPaginaRetorno("login.jsp");
}
RequestDispatcher dispatcher = request.getRequestDispatcher(this.getPaginaRetorno());
dispatcher.forward(request, response);
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeCurrentSession();
}
}
public String getPaginaRetorno() {
return paginaRetorno;
}
/**
* @param paginaRetorno the paginaRetorno to set
*/
public void setPaginaRetorno(String paginaRetorno) {
this.paginaRetorno = paginaRetorno;
}
}
Seu servlet
public class ServletController extends HttpServlet {
protected synchronized void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
new ServletServce.execute(request , response); //passa e execução para a classe servce
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP
* <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP
* <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Olá,
Não olhei muito a fundo, mas de cara tem uma coisa muito errada:
Um container web tem o direito de controlar as instâncias de servlets como ele quiser, inclusive pode instanciar um único Servlet e usar esse objeto para atender a todas as requisições durante todo o tempo que a aplicação está no ar.
O que isso implica na hora de codificar? Em um servlet é proibido usar variáveis de instância para guardar algum estado pertinente à requisição. Imagine que você está atendendo a requisição de um cliente A, guarda algumas variáveis e começa a processar; nesse meio tempo um cliente B chega para ser atendido em outra thread, mas o servidor vai reutilizar a mesma instância do Servlet. A thread do cliente B sobrescreve as variáveis e a bagunça está feita.
Procure mudar o design da sua solução, para eliminar essas variáveis de instância no Servlet.
Obrigado danilovteodoro pela ajuda mas realmente foi o que gomesrod citou, o design da aplicação tem pontos a serem refatorados, como essas variáveis de instancia na Servlet.
Encontrei o que gomesrod falou nesse artigo, apesar de ser antigo explica realmente o que está acontecendo com minha aplicação.
http://www.guj.com.br/articles/117