使用Servlet生成Excel时收到错误

时间:2018-11-06 10:02:47

标签: java servlets java-ee servlet-3.0

我创建了一段代码,用于在servlet中生成和下载excel文件。下面提供了代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String act = request.getParameter("act").toLowerCase();
    RequestDispatcher rd = request.getRequestDispatcher("sqleditor.jsp");

    try {
        if(act.equalsIgnoreCase("exec")) {
            String uqry = request.getParameter("isql");
            if ( !uqry.isEmpty() ) {
                qp = new queryProcessor(uqry);
                mp = qp.getResultSet();
                request.setAttribute("result",mp);
                rd.forward(request, response);
            } else {
                ERROR_MSG = "Please enter a query";
                request.setAttribute("errormsg", ERROR_MSG);
                rd.forward(request, response);
            }
        } else if (act.equalsIgnoreCase("excel")) {
            String uqry = request.getParameter("isql");
            if ( !uqry.isEmpty() ) {
                try {
                    response.setContentType("application/vnd.ms-excel");
                    response.setHeader("Content-Disposition", "attachment; filename=\"" + FILENAME + "\"");
                    initExcelfile(response.getOutputStream());
                } catch (Exception evar1) {
                    request.setAttribute("errormsg", evar1.getMessage());
                    rd.forward(request, response);
                }

                System.out.println("File downloaded at client successfully");
            }
        }
    } catch (AppException evar2) {
        request.setAttribute("errormsg", evar2.getmessage());
        rd.forward(request, response);
    } catch (SQLException evar3) {
        request.setAttribute("errormsg", evar3.getMessage());
        rd.forward(request, response);
    } catch (NullPointerException evar4) {
        request.setAttribute("errormsg", evar4.getMessage());
        rd.forward(request, response);
    } catch (FileNotFoundException evar5) {
        request.setAttribute("errormsg", evar5.getMessage());
        rd.forward(request, response);
    } catch (Exception evar6) {
        request.setAttribute("errormsg", evar6.getMessage());
        rd.forward(request, response);
    }
}

private void initExcelfile(ServletOutputStream outputStream) {

    HSSFWorkbook workbook = new HSSFWorkbook();
    HSSFSheet sheet = workbook.createSheet("Datatypes");

    Object[][] datatypes = {
            {"Datatype", "Type", "Size(in bytes)"},
            {"int", "Primitive", 2},
            {"float", "Primitive", 4},
            {"double", "Primitive", 8},
            {"char", "Primitive", 1},
            {"String", "Non-Primitive", "No fixed size"}
    };

    int rowNum = 0;
    System.out.println("Creating excel");

    for (Object[] datatype : datatypes) {
        Row row = sheet.createRow(rowNum++);
        int colNum = 0;
        for (Object field : datatype) {
            Cell cell = row.createCell(colNum++);
            if (field instanceof String) {
                cell.setCellValue((String) field);
            } else if (field instanceof Integer) {
                cell.setCellValue((Integer) field);
            }
        }
    }
    System.out.println("Workbook Created");

    try {
        workbook.write(outputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是当我将initExcelfile()方法移至单独的类文件并从那里调用该方法时,会收到以下错误:

ERROR [io.undertow.request] (default task-4) UT005023: Exception handling request to /sqle/sqleditor.jsp: java.lang.RuntimeException: java.lang.IllegalStateException: UT010006: Cannot call getWriter(), getOutputStream() already called
    at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:245)
    at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImplSetup(RequestDispatcherImpl.java:147)
    at io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:111)
    at com.sqle.RequestController.doPost(RequestController.java:84)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: UT010006: Cannot call getWriter(), getOutputStream() already called
    at io.undertow.servlet.spec.HttpServletResponseImpl.getWriter(HttpServletResponseImpl.java:355)
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:112)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:105)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:183)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:121)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75)
    at org.apache.jsp.sqleditor_jsp._jspService(sqleditor_jsp.java:196)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:402)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:346)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.jsp.JspFileHandler.handleRequest(JspFileHandler.java:32)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:274)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:209)
    at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:221)
    ... 42 more

请让我知道我在这里遇到的错误,因为我遇到了这个错误。

1 个答案:

答案 0 :(得分:0)

基于stacktrace,看来您是第一次这样做:

  initExcelfile(response.getOutputStream())

这将引发异常。然后,在异常处理程序中,您似乎正在尝试重定向到JSP以产生错误消息。不幸的是,这失败了,因为:

  • JSP将在响应对象上调用getWriter()来找到发送其输出的位置,
  • 您已经在响应对象上调用了getOutputStream(),并且
  • 您无法在同一getWriter()对象上同时调用getOutputStream()Response……否则您将获得IllegalStateException

如果要直接将电子表格写入输出,则在发生故障时无法重定向到JSP。即使servlet框架允许(不允许!),您也可能会得到部分电子表格,并在最后加上错误页面。用户的网络浏览器将无法理解这一点。

有两种选择:

  1. 在生成电子表格时遇到异常的情况下,请消除尝试的重定向。
  2. 保留重定向,但更改代码,以便准备和缓冲电子表格。成功生成电子表格之后,仅在 后打开响应输出流。

首先还有一个引起异常的问题。我看不到明显的线索,因此您需要自己调试。 (例如,您可以连接调试器并在异常处理程序中设置断点,然后查看捕获的异常的类,消息和调用堆栈。)