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

发布于 2024-12-02 04:14:52 字数 3171 浏览 0 评论 0原文

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

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

  1. servlet 接收 /verificon/* url 模式的请求。
  2. 它提取 /verificon/ 之后设置的任何字符串,即如果 url 为 http://domain/context/verificon/blahblah,它提取 blahblah代码>.
  3. 它检查该字符串是否是已知字符串,并简单地显示带有结果的 jsp(true / false)。

然而,尽管很简单,但在使用测试字符串运行应用程序时出现以下错误:

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) {%>

瓦利多

<% } 其他 {%>

因瓦利多

<% }%>

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>
<% }%>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葮薆情 2024-12-09 04:14:52

看这里,

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

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

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

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

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

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

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文