java.lang.IllegalStateException: getOutputStream() has already been called for this response when calling JasperReport

后端 未结 3 2124
梦谈多话
梦谈多话 2020-12-17 07:14

I am trying iReport/JasperReport in JSF 2 But while i am generating The PDF i got this error. I searched and found some similar problems and solutions, but nothing worked. S

相关标签:
3条回答
  • 2020-12-17 07:25

    For Others Help i m posting my final working (Solved) Code

    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();
    }
    

    and the xhtml

    <h:commandButton id="getPDF" value="PDF" actionListener="#{monthlyReportBean.pdf}" /> 
    
    0 讨论(0)
  • 2020-12-17 07:39

    You may not have done so directly but several things in your code are suspect and can be modified to get the desired response. The exception you've gotten does not occur for any other reason other than trying to claim the response output stream after the servlet container has attempted to do so or doing so twice

    1) The lines

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

    is making repeated (and unnecessary calls) to context resources.

    2) You've failed to call responseComplete() on your FacesContext instance which will almost certainly guarantee that writing a file for download to the stream will fail

    3)While I'm not certain on this, I'd recommend you just move your report processing from the actionListener to action on your commandButton and remove the ActionListener argument from the method signature accordingly

    4)I don't know what type jasperPrint is, but you can use JasperReport's JasperRunManager.runReportToPdfStream() function that accepts an input stream of .jasper file to output your report.

    You can combine all that and use the following :

         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) {
           //
       }
    

    Unrelated to your question, you need to be absolutely sure that the path /web/ireport/* is secure. Looks to me like a publicly accessible path.

    0 讨论(0)
  • 2020-12-17 07:41

    using FacesContext.getCurrentInstance().responseComplete(); after exporting the report may solve your problem.

    0 讨论(0)
提交回复
热议问题