响应无法在 catch 块中发送重定向

Response can't send redirect in catch block

我正在写一个 Servlet Controller.If 我没有传递任何参数,它会捕获异常并且响应会发送重定向到 index.jsp

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, Exception {
        
            response.setContentType("text/html;charset=UTF-8");
            RequestDAO requestDAO = new RequestDAOImpl();
               
        try (PrintWriter out = response.getWriter();) {

            // get request
            int rId = Integer.parseInt(request.getParameter("rId"));
            Request req = requestDAO.getRequestById(rId);

            sendDispatcher(request, response, "viewRequestMentor.jsp");
        
        } catch (Exception e) {
            
            Logger.getLogger(ViewMentorRequestDetailController.class.getName()).log(Level.SEVERE, null, e);
            session.setAttribute("error", "Cant view request detail");
            response.sendRedirect("index.jsp");
            
        }
    }

但是重定向不起作用,记录器显示异常

Severe:   java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:518)
    at controller.ViewMentorRequestDetailController.processRequest(ViewMentorRequestDetailController.java:76)
    at controller.ViewMentorRequestDetailController.doGet(ViewMentorRequestDetailController.java:103)

您遇到的问题是您正在尝试使用此处的资源:

try (PrintWriter out = response.getWriter();) {

这意味着当 try/catch 块完成时 PrintWriter 关闭。 PrintWriter 用于打印响应(body、header 和符合 HTTP 响应的所有内容),如果关闭,则没有人可以打印任何内容它。

sendRedirect 只是一个带有代码 302 的普通 HTTP 响应,应该写入响应 object (HttpServletResponse),并且有一个 header Location 通知它应该被重定向到哪里。如果您在浏览器的调试中打开“网络”选项卡,您将看到正在发出两个请求,一个用于原始 Servlet,另一个用于重定向。

您实际上不必关闭 PrintWriter,因为它是 Servlet 容器(或应用程序服务器,或您正在使用的任何东西)负责在一切设置正确后执行此操作。 HttpServletResponse 意味着我们在 doGet/doPost 方法中所做的事情更多,它有一个完整的生命周期,我们在中间进行干预,我们在 [=22] 中接收它=]/doPost/do... 并将其交还给负责在其中执行操作的下一个 Servlet Container bean。

所以,直接把带资源的try去掉,获取PrintWriter,不用关闭。重定向应该可以正常工作。

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, Exception {
        
            response.setContentType("text/html;charset=UTF-8");
            RequestDAO requestDAO = new RequestDAOImpl();
               
        try {
            PrintWriter out = response.getWriter();

            // get request
            int rId = Integer.parseInt(request.getParameter("rId"));
            Request req = requestDAO.getRequestById(rId);

            sendDispatcher(request, response, "viewRequestMentor.jsp");
        
        } catch (Exception e) {
            
            Logger.getLogger(ViewMentorRequestDetailController.class.getName()).log(Level.SEVERE, null, e);
            session.setAttribute("error", "Cant view request detail");
            response.sendRedirect("index.jsp");
            
        }
    }