在jsp中,生成pdf我得到一个java.lang.IllegalStateException:STREAM

时间:2013-08-30 15:47:42

标签: java jsp pdf jasper-reports

我被要求在现有的Web应用程序中创建一个报告(不是我自己的,我无法访问其代码)。我已经确定 JasperReports 是最简单的,因为周围有很多很好的例子......

我已经编写了下面的示例,但是浏览器显示一个空白页面,没有显示pdf。但是,如果我刷新浏览器页面,有时会显示pdf。

<%@ page  import="java.io.*"%> 
<%@ page  import="javax.servlet.*"%>
<%@ page  import="java.sql.Connection"%>
<%@ page  import="java.sql.DriverManager"%>
<%@ page  import="java.util.HashMap"%>
<%@ page  import="java.util.Map"%>
<%@ page  import="javax.servlet.ServletException"%>
<%@ page  import="javax.servlet.ServletOutputStream"%>
<%@ page  import="net.sf.jasperreports.engine.*"%>
<%@ page contentType="application/pdf" %>


    <%
         Connection conn = null;
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            conn = DriverManager.getConnection("jdbc:sqlserver://[server][\instance]:1433;databaseName=[databasename];integratedSecurity=True");
        } catch (Exception ex) {
            ex.printStackTrace();


        }


        File reportFile = new File(application.getRealPath("/bespoke/rapport/Planning.jasper"));//your report_name.jasper file
        Map parameters = new HashMap();
        byte[] bytes = JasperRunManager.runReportToPdf(reportFile.getPath(), parameters, conn);


                response.setContentType("application/pdf");
                response.setContentLength(bytes.length);
                ServletOutputStream outputStream = response.getOutputStream();
                outputStream.write(bytes, 0, bytes.length);
                outputStream.flush();
                outputStream.close();

           %>

我得到的确切错误是:

java.lang.IllegalStateException: STREAM
at org.mortbay.jetty.Response.getWriter(Response.java:616) ~[jetty-6.1.24.jar:6.1.24]
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:122) ~[servlet-api-2.5-20081211.jar:na]
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187) ~[jsp-2.1-glassfish-2.1.v20091210.jar:na]
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:180) ~[jsp-2.1-glassfish-2.1.v20091210.jar:na]

现在,我知道问题出现在代码的最后几位 问题是,当我不允许在原始程序中添加类时,如何解决这个问题?
我只能添加 .jasper 文件,并通过神恩典添加一个简单的 .jsp 页面。
再次,我知道将代码添加到 jsp 是非常糟糕的形式,但我被困在这里......

2 个答案:

答案 0 :(得分:0)

我昨天在JSP中创建并返回一个Excel文件时遇到了类似的错误。您需要删除结束(%&gt;)和打开(&lt;%)jsp标记之间的所有空格。

而不是

 <%@ page contentType="application/pdf" %>


 <%
  Connection conn = null;

成功

 <%@ page contentType="application/pdf" %><%
  Connection conn = null;

如果你留空,那么JSP调用response.getOutputStream()来创建你不想要的JspWriter,因为你需要自己调用response.getOutputStream()来返回二进制文件。

答案 1 :(得分:0)

将我的代码更改为以下内容:

<%@ page language="java" import="net.sf.jasperreports.engine.*,net.sf.jasperreports.engine.export.*" %>  
<%@ page import="org.apache.commons.lang.time.*" %>  
<%@ page import="java.sql.*,java.io.*" %>
<%
 String filename = request.getParameter("filename");
 String reporttype = request.getParameter("reporttype");
 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
 Connection conn = DriverManager.getConnection("jdbc:sqlserver://[servername]\\[instancename];databaseName=[databasename][:portnumber(remove when dynamic port is used)];integratedSecurity=True");
           System.out.println("Connection Established");
 String path = application.getRealPath("/");

 JasperPrint jasperPrint = JasperFillManager.fillReport(path + "/" + filename, null, conn);
 System.out.println("Report Created...");

 OutputStream ouputStream = response.getOutputStream();

 JRExporter exporter = null;

 if( "pdf".equalsIgnoreCase(reporttype) )
 {
      response.setContentType("application/pdf");
      exporter = new JRPdfExporter();
      exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
      exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
 }
 else if( "html".equalsIgnoreCase(reporttype) )
 {
      exporter = new JRHtmlExporter();
      exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
      exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
 }
 else if( "xls".equalsIgnoreCase(reporttype) )
 {
      response.setContentType("application/xls");
      response.setHeader("Content-Disposition", "inline; filename=\"file.xls\"");

      exporter = new JRXlsExporter();
      exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
      exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
 }
 try 
 {
      exporter.exportReport();
 } 
 catch (JRException e) 
 {
      throw new ServletException(e);
 }
 finally
 {
      if (ouputStream != null)
      {
           try
           {
                ouputStream.close();
           }
           catch (IOException ex)
           {
           }
      }
 }
%>  

不幸的不得不做这种方式,但至少是卓有成效....