在Java Servlet中转发请求时的无限循环

时间:2011-09-01 00:40:37

标签: servlets tomcat7 java-7

我希望你能帮助我解决我面临的这个问题:

我使用NetBeans创建了一个简单的Web应用程序。 截至目前,这是非常基本的。

  1. servlet接收/verificon/* url模式的请求。
  2. 它提取/verificon/之后设置的任何字符串,即如果网址为http://domain/context/verificon/blahblah,则会提取blahblah
  3. 检查此字符串是否为已知字符串,只显示带有结果的jsp(true / false)。
  4. 但是,尽管很简单,但在使用测试字符串运行应用程序时出现以下错误:

    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)
        ...
    

    然后它不断重演。

    我的servlet的processRequest方法如下。 TestData只是一个帮助类,如果字符串已知则返回Mapeo对象,如果不知道则返回null

    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);
    

    }

    非常感谢任何帮助。

    如果您需要了解任何其他信息,请告诉我。

    谢谢!

    注1:servlet的第51行是在processRequest方法结束时对rd.forward()的调用,第70行只是从doGet方法调用processRequest()。 注意2:如果我评论前向部分并取消注释PrintWriter部分,一切都按预期工作。 注3:resultado.jsp是一个纯HTML页面,带有正确的doctype def,html,head和body标签,这个: <%boolean valido = (boolean)request.getAttribute("valido");%> ... <% if(valido) {%> <p>Válido</p> <% } else {%> <p>Inválido</p> <% }%>

1 个答案:

答案 0 :(得分:12)

看这里,

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

您使用相对路径转发。它转发到http://domain/context/verificon/blahblah/WEB-INF/jsp/resultado.jsp,再次与servlet匹配。它又使用相对于servlet的http://domain/context/verificon/blahblah/WEB-INF/jsp/resultado.jsp/WEB-INF/jsp/resultado.jsp的相对路径进行转发。等等。如果你已经调试/记录了传入的请求URI,它会使一切变得更加清晰。

您需要使用绝对路径转发。使用/进行前缀。

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

无关具体问题,你在JSP中检查值的方式非常笨拙和老派。只需使用EL(已存在十多年,确保您正在阅读正确的JSP / Servlet书籍/教程):

<p>${valido ? 'Válido' : 'Inválido'}</p>