【问题标题】:Response can't send redirect in catch block响应无法在 catch 块中发送重定向
【发布时间】:2021-11-12 01:36:22
【问题描述】:

我正在写一个 Servlet 控制器。如果我不传递任何参数,它将捕获 Exception 并且响应将 sendRedirect 到 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)

【问题讨论】:

  • 在您开始发送响应后,您将无法重定向。您需要查看日志以确定实际错误是什么。
  • 当然,您会在日志中看到异常,您正在尝试捕获异常 - 然后您会立即设置错误并设置“Level.SEVERE”异常。重定向是否有效并且您看到异常?因为无论重定向是否有效,都会显示该异常。日志中是否还有另一个错误输出?
  • 我不明白。我唯一的回应是在 catch 块中。它会显示您所看到的异常
  • @backwardforward 它显示两个异常 NullPointerException 因为我没有传递任何参数,当响应尝试发送重定向时出现 IllegalStateException

标签: java servlets


【解决方案1】:

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

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

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

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

您实际上不必关闭PrintWriter,因为它是 Servlet 容器(或应用程序服务器,或您正在使用的任何东西)在一切都正确设置后负责执行此操作。 HttpServletResponse 意味着我们在doGet/doPost 方法中所做的事情更多,它有一个完整的生命周期,我们在中间进行干预,我们在doGet/doPost/@ 中接收它987654336@ 并把它交还给下一个 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");
            
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-26
    • 2020-11-19
    • 2013-08-07
    • 2013-09-14
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多