【问题标题】:java.lang.IllegalStateException: getOutputStream() has already been called for this response when calling JasperReportjava.lang.IllegalStateException:调用 JasperReport 时已为此响应调用 getOutputStream()
【发布时间】:2022-02-08 03:56:11
【问题描述】:

我正在 JSF 2 中尝试 iReport/JasperReport 但是,当我生成 PDF 时,我得到了这个错误。 我搜索并发现了一些类似的问题和解决方案,但没有任何效果。很抱歉再次发布相同的问题。但是我尝试了所有可能的解决方案,但没有一个对我有用。请帮忙

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:637)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:214)
at com.sun.faces.context.ExternalContextImpl.getResponseOutputWriter(ExternalContextImpl.java:723)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.createResponseWriter(FaceletViewHandlingStrategy.java:1009)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:382)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

以下是函数

public void init() throws IOException, JRException {
    JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(listReportObjects);
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
    servletOutputStream = httpServletResponse.getOutputStream();
    ServletContext servletContext = (ServletContext) externalContext.getContext();
    String reportLocation = servletContext.getRealPath("/web/ireport/monthlyReport.jasper");
    jasperPrint = JasperFillManager.fillReport(reportLocation, new HashMap<String, Object>(), beanCollectionDataSource);
}


public void PDF(ActionEvent actionEvent) throws IOException, JRException {
    System.out.println("*****************PDF*********************");
    init();
    JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
}

还有 XHTML 代码: ;

我的 POM 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.nic</groupId>
<artifactId>RFD</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>RFD</name>

<properties>
    <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <netbeans.hint.deploy.server>Tomcat</netbeans.hint.deploy.server>
</properties>

<dependencies>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>2.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.3.2</version>
        <scope>provided</scope>
    </dependency>        
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.1.13</version>
    </dependency>
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.1.13</version>
    </dependency>
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>
    <!-- PrimeFaces -->
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>3.4.1</version>
    </dependency>  
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>all-themes</artifactId>
        <version>1.0.8</version>
    </dependency>
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>primefaces-extensions</artifactId>
        <version>0.6.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2.2</version>
    </dependency>       
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate</artifactId>
        <version>3.2.6.ga</version>
        <exclusions>
            <exclusion>
                <artifactId>antlr</artifactId>
                <groupId>antlr</groupId>
            </exclusion>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.3.2.GA</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>javax.sql</groupId>
        <artifactId>jdbc-stdext</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>javax.transaction</groupId>
        <artifactId>jta</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.21</version>
    </dependency>
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.servicemix.bundles</groupId>
        <artifactId>org.apache.servicemix.bundles.jettison</artifactId>
        <version>1.0.1_5</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.1.1.Final</version>
        <type>jar</type>
        <exclusions>
            <exclusion>
                <artifactId>antlr</artifactId>
                <groupId>antlr</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>antlr</groupId>
        <artifactId>antlr</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.8.3</version>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.5</version>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>            
        <version>4.8.0</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-beanutils</artifactId>
                <groupId>commons-beanutils</groupId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>

    <plugins>        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>               
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <compilerArguments>
                    <endorseddirs>${endorsed.dir}</endorseddirs>
                </compilerArguments>                    
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.1</version>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${endorsed.dir}</outputDirectory>
                        <silent>true</silent>
                        <artifactItems>
                            <artifactItem>
                                <groupId>javax</groupId>
                                <artifactId>javaee-endorsed-api</artifactId>
                                <version>6.0</version>
                                <type>jar</type>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jasperreports-maven-plugin</artifactId>
            <version>1.0-beta-2</version>
            <configuration>
                <sourceDirectory>/web/ireport</sourceDirectory>
                <outputDirectory>/web/ireport</outputDirectory>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile-reports</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<repositories>
    <repository>
        <url>http://download.eclipse.org/rt/eclipselink/maven.repo/</url>
        <id>eclipselink</id>
        <layout>default</layout>
        <name>Repository for library EclipseLink (JPA 2.0)</name>
    </repository>
    <repository>
        <url>http://repository.primefaces.org/</url>
        <id>primefaces</id>
        <layout>default</layout>
        <name>Repository for library PrimeFaces 3.2</name>
    </repository>                
</repositories>

请帮忙

我没有在项目的其他任何地方使用函数 getOutputStream()。

【问题讨论】:

    标签: jsf-2 jasper-reports ireport servletexception jasper-plugin


    【解决方案1】:

    您可能没有直接这样做,但您的代码中有几处是可疑的,可以对其进行修改以获得所需的响应。除了在 servlet 容器尝试这样做或这样做两次后试图声明响应输出流之外,您得到的异常不会发生任何其他原因

    1) 线条

     ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
     HttpServletResponse httpServletResponse = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
     ServletContext servletContext = (ServletContext) externalContext.getContext();
    

    正在对上下文资源进行重复(和不必要的调用)。

    2) 您未能在您的 FacesContext 实例上调用 responseComplete(),这几乎肯定会保证将要下载的文件写入流将失败

    3)虽然我对此不确定,但我建议您将您的报告处理从commandButton 上的actionListener 移动到action,并相应地从方法签名中删除ActionListener 参数

    4)我不知道jasperPrint是什么类型,但是你可以使用JasperReport的JasperRunManager.runReportToPdfStream()函数接受.jasper文件的输入流来输出你的报告。

    您可以结合所有这些并使用以下内容:

         FacesContext facesContext = FacesContext.getCurrentInstance(); //Get the context ONCE
         HttpServletResponse response = (HttpServletResponse)       facesContext.getExternalContext().getResponse();
         InputStream reportStream =   facesContext.getExternalContext().getResourceAsStream("/web/ireport/monthlyReport.jasper");
    try {
        ServletOutputStream servletOutputStream = response.getOutputStream();
        response.setContentType("application/pdf");
        facesContext.responseComplete();
    
        try {  // Replace this with your desired JR utility method
            JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, params);
        } catch (JRException ex) {
            //
        }
        servletOutputStream.flush();
        servletOutputStream.close();
    } catch (IOException ex) {
       //
    } catch (Exception ex) {
           //
       }
    

    与您的问题无关,您需要绝对确定路径 /web/ireport/* 是安全的。在我看来,这是一条可公开访问的路径。

    【讨论】:

    • 谢谢@kolossus,我会尝试你的建议并告诉你,关于路径/web/ireport/*我有一个过滤器。
    • 它可以工作,但是当我从它调用函数时,我的一天被&lt;p:commandButton&gt; 毁了,生成的报告文件没有进入浏览器,经过这么多不同的试验,我尝试了&lt;h:commandButton&gt; 它有效.知道如何使用&lt;p:commanButton&gt; 来做同样的事情吗?再次感谢 kolossus :)
    • 您需要在&lt;p:command button/&gt; 上创建ajax="false",因为您需要一个完整的Web 应用程序生命周期请求,而不是ajax 请求,才能达到预期的结果。这是&lt;h:commandButton/&gt; 工作的唯一原因:)。
    • @BhaskarMalakar,上面的答案,忘记引用您的用户名
    • 也适用于我,谢谢。在我的情况下,将 facesContext 提取到变量中并在最后关闭响应。 2 小时寻找原因!
    【解决方案2】:

    为了其他人帮助我发布我的最终工作(已解决)代码

    public void init() throws IOException, JRException {
        JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(listReportObjects);
        String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/web/ireport/monthlyReport.jasper");
        jasperPrint = JasperFillManager.fillReport(reportPath, new HashMap(), beanCollectionDataSource);
        httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
    }
    
    
    public void pdf() throws IOException, JRException {
        init();
        httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
        servletOutputStream = httpServletResponse.getOutputStream();
        JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
        FacesContext.getCurrentInstance().responseComplete();
    }
    

    和xhtml

    <h:commandButton id="getPDF" value="PDF" actionListener="#{monthlyReportBean.pdf}" /> 
    

    【讨论】:

      【解决方案3】:

      在导出报告后使用FacesContext.getCurrentInstance().responseComplete(); 可能会解决您的问题。

      【讨论】:

      • Stack Overflow 不像一个讨论论坛,每个人都在达成一致后互相重复,变得难以消化。没有必要重复已经给出的答案。一旦你有足够的声誉,如果你觉得它有帮助,你就可以投票赞成。
      【解决方案4】:

      我解决了在 h:form 之后移动我的命令按钮的问题,我的意思是,在任何容器之外并且它可以工作,所以我假设命令在 div 或容器中时有一些东西,我注意到因为“ajax” atributte 设置为 False,但仍然给我和容器的“更新”。

      我有这个帮助。

      【讨论】:

        猜你喜欢
        • 2023-03-08
        • 2020-01-08
        • 2012-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多