为了账号安全,请及时绑定邮箱和手机立即绑定

使用 try-catch 资源在 Servlet 中提交响应后无法转发

使用 try-catch 资源在 Servlet 中提交响应后无法转发

Helenr 2022-07-20 12:22:46
下面的方法抛出:Servlet DetailCakeServlet 的 Servlet.service() 抛出异常java.lang.IllegalStateException: Cannot forward after response has been committed.代码 try (PrintWriter out = response.getWriter()) {        /* TODO output your page here. You may use following sample code. */        CakeDAO dao = new CakeDAO();        String strID = request.getParameter("id");        int id = Integer.parseInt(strID);        request.setAttribute("cake", dao.getCakeById(id));        request.getRequestDispatcher("/WEB-INF/detail.jsp").forward(request, response);    }catch (Exception ex) {        request.getRequestDispatcher("/WEB-INF/error.jsp").forward(request, response);    }但是当我删除资源对象时,它就可以工作了。可能是什么原因 ?
查看完整描述

2 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

要么做一个没有输出的转发:


try {

    CakeDAO dao = new CakeDAO();

    String strID = request.getParameter("id");

    int id = Integer.parseInt(strID);

    request.setAttribute("cake", dao.getCakeById(id));

    request.getRequestDispatcher("/WEB-INF/detail.jsp").forward(request, response);

} catch (Exception ex) {

    request.getRequestDispatcher("/WEB-INF/error.jsp").forward(request, response);

}

或者做:


try {

    CakeDAO dao = new CakeDAO();

    String strID = request.getParameter("id");

    int id = Integer.parseInt(strID);

    PrintWriter out = response.getWriter();

    out.println("Cake: " + dao.getCakeById(id)); // Hereafter an exception would err.

    // NEVER forward: ... .forward(request, response);

} catch (Exception ex) {

    request.getRequestDispatcher("/WEB-INF/error.jsp").forward(request, response);

}

Try-with-resources 会自动关闭,并且不需要。在转发时甚至会引发错误。


更重要的是,没有得到作家,你是更好的。在实际写入输出之后(缓冲 I/O!),转发是错误的,因此 catch 中的转发是脏的。


查看完整回答
反对 回复 2022-07-20
?
函数式编程

TA贡献1807条经验 获得超9个赞

如此处所述(在规范中没有很快找到它),在进入 catch 块之前,try-with-resources 构造将尝试关闭在 try 块中打开的资源- 即您的out, 因此response, 已经当您尝试在catch块中重定向时关闭。我建议通过以下方式处理可能的异常:


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

  try {

    CakeDAO dao = new CakeDAO();

    String strID = request.getParameter("id");

    int id = Integer.parseInt(strID);

    request.setAttribute("cake", dao.getCakeById(id));

    request.getRequestDispatcher("/WEB-INF/detail.jsp").forward(request, response);

  }catch (Exception ex) {

    request.getRequestDispatcher("/WEB-INF/error.jsp").forward(request, response);

  }

}

实际上,我在您的代码中没有看到任何使用out,所以整个 try-with-resources 块只是多余的。


查看完整回答
反对 回复 2022-07-20
  • 2 回答
  • 0 关注
  • 225 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信