java - requestDispatcher#forward() 上的 Tomcat 无限循环。堆栈溢出错误

标签 java tomcat servlets requestdispatcher deployment-descriptor

Tomcat 在不断重复这些行后给我 StackOverflowError,其中 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 个操作同时登陆同一页面。我以为我会像这样设置它。每个 Action 都经过它自己的 Filter,它们都以分派(dispatch)给 JSPServlet 结束。

我的 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。这是导致 StackOverflowError 的无限循环。

如果 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>

关于java - requestDispatcher#forward() 上的 Tomcat 无限循环。堆栈溢出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48549551/

相关文章:

apache - 将所有流量重定向到 www https

java - 如何在不使用插件的情况下从 Jenkins 将 war 文件部署到 Tomcat

java - 内部服务器错误

java - Java VM 上的 Android 错误。运行 Java SE 7

java - 如何访问 eclipse VM 参数中指定的属性?

java - 单击按钮时如何销毁 Activity ?

java - Servlet.service() 抛出 NullPointerException

java - 适配器类与数据类中的 toXXX() 方法

eclipse - 在eclipse vs命令行中启动tomcat

spring - 扩展 SpringBootServletInitializer 时如何注册 DispatcherServlets 并重写 onStartup