Ошибка при создании Excel с использованием сервлета - PullRequest
0 голосов
/ 06 ноября 2018

Я создал кусок кода для генерации и загрузки файла 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 голосов
/ 06 ноября 2018

Исходя из стека трассировки, похоже, что вы впервые делаете это:

  initExcelfile(response.getOutputStream())

, который выбрасывает исключение. Затем в обработчике исключений вы, кажется, пытаетесь перенаправить на JSP, чтобы выдать сообщение об ошибке. К сожалению, это не удается, потому что:

  • JSP собирается вызвать getWriter() объекта ответа, чтобы найти место для отправки своего вывода,
  • вы уже вызвали getOutputStream() для объекта ответа и
  • вы не можете вызывать getWriter() и getOutputStream() для одного и того же Response объекта ... или вы получите IllegalStateException!

Если вы собираетесь записать электронную таблицу непосредственно в выходной файл, вы НЕ МОЖЕТЕ перенаправить ее на JSP в случае сбоя. Даже если инфраструктура сервлета это позволяет (это не так!), Вы будете обязаны получить частичную электронную таблицу со страницей ошибок, прикрепленной в конце. Веб-браузер пользователя не сможет понять это.

Есть две альтернативы:

  1. Избавьтесь от этой попытки перенаправления в случае, если вы получаете исключение при создании электронной таблицы.
  2. Сохраняйте перенаправление, но изменяйте свой код, чтобы подготовить и буферизовать электронную таблицу. Открывайте поток вывода ответа только после того, как вы успешно сгенерировали электронную таблицу.

Существует также вопрос, что является причиной исключения в первую очередь. Я не вижу очевидных подсказок, поэтому вам придется отлаживать их самостоятельно. (Например, вы можете присоединить отладчик и установить точку останова в обработчике исключений и посмотреть на класс перехваченного исключения, сообщение и стек вызовов.)

...