I am creating a project with struts and I have a problem using Jasper IReports. I want to export some info into a pdf file and I keep getting the java.lang.IllegalStateException: getOutputStream() has already been call... Exception due to openning a ServletOutputStream in my code when the page already opens a PrintWriter.
The code is in the model (so it is not in the jsp, it's in a java file), as it follows:
public void handle(HttpServletResponse res, Connection connection, String path)throws Exception{
ServletOutputStream out = null;
try {
JasperDesign jasperDesign = JRXmlLoader.load(path);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
byte[] bytes = JasperRunManager.runReportToPdf(jasperReport, null, connection);
res.setContentType("application/pdf");
res.setContentLength(bytes.length);
out = res.getOutputStream();
out.write(bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.flush();
out.close();
}
I have checked the connection, the path and the HttpServletResponse and are all working fine.
I'm very newbie with Jasper Reports as well as with coding stuff into PDF so you can -correctly- suposse that I have a minimal idea of what I am doing here and that, obviously my code is copy/pasted from somewhere through the net.
I have tried to use PrintWriter instead of OutputStream, transforming bytes into a String and using the PrintWriter.append(String) method (allthought is not String is CharSequence), but it doesn't extract the data into the PDF.
I have also tried to get the PrintWriter, close it to open the OutputStream (didn't work) or flush it (neither).
Any help with a solution to use any out that could show the data in a pdf would be great. Thanks a lot!
Own answer:
I have put in the path a jrxml that actually connects to the database and gets some real data out and suddendly it worked, the PDF opened in mozilla, but the Exception keeps happening. I do not know how I can throw and exception (I have debugged and the Exception happens in the same place) and be able to see the PDF.
So I can only keep searching for what actually happens here. I will answer with anything I find (probably on monday).
Thanks simonlord and Jim Rush for your help! :)
Edit: By the way, here is the stacktrace (it's in Spanish, if needed I will translate anything you don't understand): Edit again: Seems I didn't copy the '1' in the 15th-Jan-2010... could create confusion about a trace from the 5th-Jan insetad. Corrected.
Would be useful to see the stack trace.
You might try running a sanity check first though: Modify that code to simply write a static string (hello world) to the ServletOutputStream and set content type to text/html. As that should work fine:
HTH
How exactly is the code invoked? Judging from the stacktrace it look like that you're running the Java class with the
handle
method using scriptlets inside a JSP file (theinicio2.jsp
to be precise). After that the Java class has written the report to theOutputStream
, the JSP file would continue with outputting the remnant of the file itself (including whitespace!), which would implicitly invoke thegetWriter()
to write it to response. Exactly that would cause anIllegalStateException
as you're facing now when thegetOutputStream()
is already been called before in the Java class.It's good that Java code is been placed in a Java class, but that doesn't mean that you may still use JSP to invoke it. The JSP should not contain any single line of Java code. JSP itself is as being a view technology part of the output. To fix this all, just have a Struts action class (or a
HttpServlet
) which you can invoke by a HTML<form>
or<a>
.Some ideas: