Tomcat requestDispatcher#forward() 无限循环。堆栈溢出错误
Tomcat infinte loop on requestDispatcher#forward(). StackOverflowError
Tomcat 在不断重复这些行后给我 WhosebugError,其中 DiceBoardDispatcher
是我的 HttpServlet,在第 34 行我调用 requestDispatcher#forward()
.
nl.rickhurkens.rollDice.web.diceBoard.DiceBoardDispatcher.doGet(DiceBoardDispatcher.java:34)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
nl.rickhurkens.rollDice.web.diceBoard.DiceBoardDispatcher.doGet(DiceBoardDispatcher.java:34)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
我想这与我的部署有关,这是我的相关部分 web.xml:
<servlet-mapping>
<servlet-name>DiceBoard</servlet-name>
<url-pattern>/dices/*</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>RollDiceFilter</filter-name>
<url-pattern>/dices/roll</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SetSettingsFilter</filter-name>
<url-pattern>/dices/setup</url-pattern>
</filter-mapping>
我想做的是让 2 个操作同时登陆同一页面。我以为我会像这样设置它。每个动作都经过自己的 Filter
,它们都以 Servlet
结束,然后分派到 JSP
.
我的 url-patter 映射曾经是 /diceBoard/*
,这是网络应用程序中某处的文件夹。从那里更改为 /dices/*
解决了转到 url/dices
时的问题。现在我可以正常访问该页面,但是当转到 url/dices/roll
时,我得到了无限循环(无论是 POST 还是 GET)。
编辑:
我的 servlet 代码:
public class DiceBoardDispatcher extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
RequestDispatcher view = request.getRequestDispatcher("diceBoardPage.jsp");
view.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher view = request.getRequestDispatcher("diceBoardPage.jsp");
view.forward(request, response);
}
}
和 RollDiceFilter:
public class RollDiceFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
HttpSession session = req.getSession();
DiceBoard diceBoard = (DiceBoard)session.getAttribute("diceBoard");
String[] lockedValues = req.getParameterValues("lock");
diceBoard.unlockAllDice();
if (lockedValues != null) {
for (String value : lockedValues) {
if (value != null) {
try {
diceBoard.lockDice(Integer.parseInt(value));
} catch (DiceNotInCollectionException e) {
// TODO: redirect to error page.
e.printStackTrace();
}
}
}
}
diceBoard.getCup().roll();
chain.doFilter(req, res);
}
public void init(FilterConfig fConfig) throws ServletException { }
public void destroy() { }
}
这是您的错误所在的行:
RequestDispatcher view = request.getRequestDispatcher("diceBoardPage.jsp");
根据 getRequestDispatcher API,输入 uri 相对于当前 servlet 上下文,因此当您在
处执行 servlet 时
/dices/roll
... 并且它执行到 "diceBoardPage.jsp" 的调度,它实际上是调度到
/dices/diceBoardPage.jsp
这个模式映射到哪个 servlet?根据您的部署描述符,每个以“/dices/*”开头的 URL 都映射到 DiceBoard
。 IE。同一个 servlet。这是导致 WhosebugError 的无限循环。
如果 JSP 必须位于 dices
uri 中,则必须限制映射 DiceBoard
servlet 的 URL 模式。如果需要,请不要犹豫添加几个值:
<servlet-mapping>
<servlet-name>DiceBoard</servlet-name>
<url-pattern>/dices/one</url-pattern>
<url-pattern>/dices/two</url-pattern>
<url-pattern>/dices/three</url-pattern>
</servlet-mapping>
Tomcat 在不断重复这些行后给我 WhosebugError,其中 DiceBoardDispatcher
是我的 HttpServlet,在第 34 行我调用 requestDispatcher#forward()
.
nl.rickhurkens.rollDice.web.diceBoard.DiceBoardDispatcher.doGet(DiceBoardDispatcher.java:34)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
nl.rickhurkens.rollDice.web.diceBoard.DiceBoardDispatcher.doGet(DiceBoardDispatcher.java:34)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
我想这与我的部署有关,这是我的相关部分 web.xml:
<servlet-mapping>
<servlet-name>DiceBoard</servlet-name>
<url-pattern>/dices/*</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>RollDiceFilter</filter-name>
<url-pattern>/dices/roll</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SetSettingsFilter</filter-name>
<url-pattern>/dices/setup</url-pattern>
</filter-mapping>
我想做的是让 2 个操作同时登陆同一页面。我以为我会像这样设置它。每个动作都经过自己的 Filter
,它们都以 Servlet
结束,然后分派到 JSP
.
我的 url-patter 映射曾经是 /diceBoard/*
,这是网络应用程序中某处的文件夹。从那里更改为 /dices/*
解决了转到 url/dices
时的问题。现在我可以正常访问该页面,但是当转到 url/dices/roll
时,我得到了无限循环(无论是 POST 还是 GET)。
编辑: 我的 servlet 代码:
public class DiceBoardDispatcher extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
RequestDispatcher view = request.getRequestDispatcher("diceBoardPage.jsp");
view.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher view = request.getRequestDispatcher("diceBoardPage.jsp");
view.forward(request, response);
}
}
和 RollDiceFilter:
public class RollDiceFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
HttpSession session = req.getSession();
DiceBoard diceBoard = (DiceBoard)session.getAttribute("diceBoard");
String[] lockedValues = req.getParameterValues("lock");
diceBoard.unlockAllDice();
if (lockedValues != null) {
for (String value : lockedValues) {
if (value != null) {
try {
diceBoard.lockDice(Integer.parseInt(value));
} catch (DiceNotInCollectionException e) {
// TODO: redirect to error page.
e.printStackTrace();
}
}
}
}
diceBoard.getCup().roll();
chain.doFilter(req, res);
}
public void init(FilterConfig fConfig) throws ServletException { }
public void destroy() { }
}
这是您的错误所在的行:
RequestDispatcher view = request.getRequestDispatcher("diceBoardPage.jsp");
根据 getRequestDispatcher API,输入 uri 相对于当前 servlet 上下文,因此当您在
处执行 servlet 时/dices/roll
... 并且它执行到 "diceBoardPage.jsp" 的调度,它实际上是调度到
/dices/diceBoardPage.jsp
这个模式映射到哪个 servlet?根据您的部署描述符,每个以“/dices/*”开头的 URL 都映射到 DiceBoard
。 IE。同一个 servlet。这是导致 WhosebugError 的无限循环。
如果 JSP 必须位于 dices
uri 中,则必须限制映射 DiceBoard
servlet 的 URL 模式。如果需要,请不要犹豫添加几个值:
<servlet-mapping>
<servlet-name>DiceBoard</servlet-name>
<url-pattern>/dices/one</url-pattern>
<url-pattern>/dices/two</url-pattern>
<url-pattern>/dices/three</url-pattern>
</servlet-mapping>