Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite loop when forwarding a request in a Java Servlet

I hope you can help me with this problem I'm facing:

I created a simple web application using NetBeans. As of now, it is very basic.

  1. A servlet receives requests on the /verificon/* url pattern.
  2. It extracts whatever string is set after /verificon/, i.e. if the url was http://domain/context/verificon/blahblah, it extracts blahblah.
  3. It checks if such string is a known string, and simply displays a jsp with the result (true / false).

However, as simple as it is, I get the following error when running the application with a test string:

javax.servlet.ServletException: 
The server side component of the HTTP Monitor has detected a java.lang.StackOverflowError.
This happens when there is an infinite loop in the web module.
Correct the cause of the infinite loop before running the web module again.

org.netbeans.modules.web.monitor.server.MonitorFilter.rethrow(MonitorFilter.java:1648)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:473)
mx.tegu.kdor.web.iu.ServletVerificon.processRequest(ServletVerificon.java:51)
mx.tegu.kdor.web.iu.ServletVerificon.doGet(ServletVerificon.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
mx.tegu.kdor.web.iu.ServletVerificon.processRequest(ServletVerificon.java:51)
mx.tegu.kdor.web.iu.ServletVerificon.doGet(ServletVerificon.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
mx.tegu.kdor.web.iu.ServletVerificon.processRequest(ServletVerificon.java:51)
mx.tegu.kdor.web.iu.ServletVerificon.doGet(ServletVerificon.java:70)
    ...

Then it just keeps repeating itself.

My servlet's processRequest method is as follows. TestData is nothing but a helper class that returns a Mapeo object if the string is known or null if it isn't.

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");

String h = request.getRequestURI().replaceFirst(request.getContextPath() + "/verificon/", "");

TestData td = TestData.getInstance();

Mapeo m = td.getMapeo(h);

boolean valido = false;
if(m != null) {
  valido = true;
}

request.setAttribute("valido", valido);

/*
PrintWriter out = response.getWriter();
out.write("Válido?: " + valido);
out.close();
*/

String respuesta = "WEB-INF/jsp/resultado.jsp";
// Como regla general, forward se utiliza para los GET y sendRedirect para los POST
RequestDispatcher rd = request.getRequestDispatcher(respuesta);
rd.forward(request, response);

}

Any help is really appreciated.

If there is any additional information you need to know, please tell me.

Thank you!

Note 1: Line 51 of the servlet is the call to rd.forward() at the end of the processRequest method, and line 70 is simply the call to processRequest() from the doGet method. Note 2: Everything works as expected if I comment the forward section and uncomment the PrintWriter section. Note 3: resultado.jsp is a plain HTML page with proper doctype def, html, head and body tags and this: <%boolean valido = (boolean)request.getAttribute("valido");%> ... <% if(valido) {%> <p>Válido</p> <% } else {%> <p>Inválido</p> <% }%>

like image 380
ahpoblete Avatar asked Sep 01 '11 00:09

ahpoblete


1 Answers

Look here,

String respuesta = "WEB-INF/jsp/resultado.jsp";
RequestDispatcher rd = request.getRequestDispatcher(respuesta);
// ...

You're forwarding using a relative path. It is forwarding to http://domain/context/verificon/blahblah/WEB-INF/jsp/resultado.jsp which matches the servlet again. It is in turn forwarding using a relative path to http://domain/context/verificon/blahblah/WEB-INF/jsp/resultado.jsp/WEB-INF/jsp/resultado.jsp which matches the servlet again. Etcetera. It would have made everything much more clear if you have debugged/logged the incoming request URI.

You need to forward using an absolute path instead. Prefix it with /.

String respuesta = "/WEB-INF/jsp/resultado.jsp";
// ...

Unrelated to the concrete problem, the way how you're checking the value in JSP is very clumsy and old school. Just use EL (which exist already over a decade, ensure that you're reading the proper JSP/Servlet books/tutorials):

<p>${valido ? 'Válido' : 'Inválido'}</p>
like image 138
BalusC Avatar answered Nov 11 '22 08:11

BalusC