在 Java Servlet 中转发请求时出现无限循环
我希望您能帮助我解决我面临的这个问题:
我使用 NetBeans 创建了一个简单的 Web 应用程序。 到目前为止,这是非常基本的。
- servlet 接收
/verificon/*
url 模式的请求。 - 它提取
/verificon/
之后设置的任何字符串,即如果 url 为http://domain/context/verificon/blahblah
,它提取blahblah
代码>. - 它检查该字符串是否是已知字符串,并简单地显示带有结果的 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.
- A servlet receives requests on the
/verificon/*
url pattern. - It extracts whatever string is set after
/verificon/
, i.e. if the url washttp://domain/context/verificon/blahblah
, it extractsblahblah
. - 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看这里,
您正在使用相对路径进行转发。它转发到再次与 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,一切都会变得更加清晰。您需要使用绝对路径进行转发。前缀为
/
。与具体问题无关,在 JSP 中检查值的方式非常笨拙和老派。只需使用 EL (它已经存在十多年了,确保您正在阅读正确的 JSP/Servlet 书籍/教程) :
Look here,
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 tohttp://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
/
.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):