java.lang.IllegalStateException:调用 JasperReport 时已为此响应调用 getOutputStream()

问题描述 投票:0回答:4

我正在 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
4个回答
10
投票

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

1) 线条

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

正在重复(且不必要地调用)上下文资源。

2) 您未能在

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

3)虽然我对此不确定,但我建议您将报告处理从

actionListener
移动到
action
上的
commandButton
,并相应地从方法签名中删除
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/*
是安全的。在我看来,这就像一条可公开访问的路径。


6
投票

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

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}" /> 

1
投票

导出报告后使用

FacesContext.getCurrentInstance().responseComplete();
可能会解决您的问题。


0
投票

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

我需要这个帮助。

© www.soinside.com 2019 - 2024. All rights reserved.