下载PDF后无法调用sendRedirect()

时间:2015-08-22 19:22:04

标签: servlets command response illegalstateexception

我看到很多问题,比如我要问的问题,但他们并不完全是我要找的东西。

我正在使用Command模式,想要创建PDF文件并下载它。创建是完美的,但是当我想下载它时,它会开始下载并抛出异常。

  

java.lang.IllegalStateException:在提交响应后无法调用sendRedirect()      org.apache.jasper.JasperException:java.lang.IllegalStateException:已为此响应调用了getOutputStream()      java.lang.IllegalStateException:已为此响应调用了getOutputStream()

这是我在Command Pattern中的代码

@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException, AppException {
    String fontPath = request.getServletContext().getRealPath(AppConstants.FONT_PATH);
    DBManager db = DBManager.getInstance();
    String ticketCode = request.getParameter("ticketCode");
    String place = request.getParameter("place");
    int amountTickets = Integer.valueOf(place);
    String flightName = Encoding.encoding(request.getParameter("flightName"));
    User user = (User) request.getSession().getAttribute("client");
    String locale = (String) request.getServletContext().getAttribute("currentLocale");
    db.updateFlightTickets(flightName, --amountTickets);
    ///////create pdf document and represent it to the byte array
    ByteArrayOutputStream baos =ReportCreator.createReport(locale, fontPath, ticketCode, place, user,
                db.getFlightByName(flightName));
    response.setContentType("application/pdf");
    response.setContentLength(baos.size());
    response.setHeader("Content-Transfer-Encoding", "binary");
    response.setHeader("Content-Disposition","attachment; filename=\"Ticket\"");
    OutputStream os = response.getOutputStream();
    baos.writeTo(os);
    os.flush();
    os.close();
    return Path.SUCCESS;
}

这是我的"成功页面",抱歉但无法添加更多,声誉不足

        <fmt:message key="success_jsp.label.success" />

这是我的servlet代码

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    process(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    process(request, response);
}

private void process(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    String commandName = request.getParameter("command");
    Command command = CommandContainer.get(commandName);
    String forward = "";
    try {
        forward = command.execute(request, response);
    } catch (AppException ex) {
        request.setAttribute("errorMessage", ex.getMessage());
    }
    if (forward.equals(Path.SUCCESS)) {
        response.sendRedirect(forward);
    } else {
        request.getRequestDispatcher(forward).forward(request, response);

    }
}

JSP中的部分代码,其中click是调用servlet

<td><a  href="Controller?command=buyTicket&flightName=${item.name}&place=${item.amountTickets}&ticketCode=<token:generate/>"><button><fmt:message key="welcome_jsp.submit.buy_ticket" /></button></a></td>

我该如何避免呢?

1 个答案:

答案 0 :(得分:0)

例外情况表示您在重定向请求/响应时尝试使用请求/响应,或者反之,它无效。

重定向请求后,您无法对请求/响应执行任何其他操作,因此获取输出流并向其写入内容完全是疯了。

反之亦然,写东西然后重定向会导致浏览器忽略响应数据,或者服务器上的异常,因为我猜你得到了。(但这取决于容器)

因此,您要么不重定向浏览器,要么在pdf文件中提供您尝试重定向的目标servlet / cgi。

=================

您目前的情况/问题:

服务器设置content-lengthcontent-type,...并开始向浏览器写下一些流,因为您还没有设置任何状态,容器将设置默认值{{1这表示请求有一些正确的响应。

然后浏览器将获得一些数据(pdf文件)作为200 OK数据(并考虑完成),现在,一旦响应几乎完成,你将如何重定向用户?!!?!!?!< / p>

我仍然不明白你为什么要在请求几乎关闭时重定向?您想在下载完成后重定向用户吗?你做不到。