The Jasper Reports servlet stopped working after calling response.getOutputStream() - java

I have code such as below. The program stopped working at line servletOutputStream = response.getOutputStream();. I don't know how to resolve this? Can anybody help me with this problem?
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException, JRException, ParserConfigurationException, SAXException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println ("<html>");
out.println (" <head>");
out.println (" <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
out.println (" <title>JSP Page</title>");
out.println (" </head>");
out.println (" <body>");
out.println (" <h1>Hello iReport!</h1>");
String resourceName = "D:/classic.jrxml";
response.setContentType("application/pdf");
ServletOutputStream servletOutputStream = null;
servletOutputStream = response.getOutputStream(); // <--
InputStream reportStream = getServletConfig().getServletContext().getResourceAsStream(resourceName);
try {
Driver driver = new org.gjt.mm.mysql.Driver();
DriverManager.registerDriver(driver);
String conString = "jdbc:mysql://localhost:3306/quanlynhasach";
Properties info = new Properties();
info.setProperty("characterEncoding", "utf8");
info.setProperty("user", "root");
info.setProperty("password", "");
Connection con = DriverManager.getConnection(conString, info);
JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream,new HashMap<Object, Object>(), con);
con.close();
}catch(Exception e){
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
response.setContentType("text/plain");
response.getOutputStream().print(stringWriter.toString());
}
out.println (" </body>");
out.println ("</html>");
} finally {
out.close();
}
} // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
try {
processRequest(request, response);
} catch (ParserConfigurationException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
} catch (SAXException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (SQLException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
} catch (JRException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Handles the HTTP <code>POST</code> method.
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
try {
processRequest(request, response);
} catch (ParserConfigurationException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
} catch (SAXException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (SQLException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
} catch (JRException ex) {
Logger.getLogger(iReport.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Returns a short description of the servlet.
* #return a String containing servlet description
*/
#Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>

Look here:
PrintWriter out = response.getWriter();
// *snip*
servletOutputStream = response.getOutputStream();
You're getting both the Writer and OutputStream from the response. This is not allowed. Read their javadocs:
getOutputStream()
ServletOutputStream getOutputStream() throws java.io.IOException
Returns a ServletOutputStream suitable for writing binary data in the response. The servlet container does not encode the binary data.
Calling flush() on the ServletOutputStream commits the response. Either this method or getWriter() may be called to write the body, not both.
and
getWriter()
java.io.PrintWriter getWriter() throws java.io.IOException
Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding(). If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.
Calling flush() on the PrintWriter commits the response.
Either this method or getOutputStream() may be called to write the body, not both.
(emphasis mine)
The problem is in your particular case however much bigger. You're attempting to inline the PDF result of a Jasper Report between those HTML tags within a HTML response. I'm not sure what you thought or smoked while you wrote the code, but that is definitely not going to work. You need to rewrite the servlet that way so that it only returns the PDF and not that bunch of HTML noise. You should move all that HTML out the servlet into some JSP file. Then, you can call that servlet by a simple download link in the JSP
Download PDF
or inside an <iframe> (yes, in JSP)
<iframe src="yourServletUrl" style="width: 500px; height: 300px;"></iframe>
or in an <object> (also here, just in JSP)
<object data="yourServletUrl" type="application/pdf" width="500" height="300" />
Just put that HTML in a JSP page, open the JSP in browser and the webbrowser will take care that the servlet will be invoked and that the PDF will be represented the way you intended.
Your other problem is that the exception handling is not really good. You'll see completely nothing this way as the response buffer is not been resetted. You should instead be doing a
} catch (Exception e) {
throw new ServletException("descriptive message here", e);
}
as the container knows perfectly how to handle exceptions.
That both your doGet() and doPost() are doing exactly the same is by the way also a design smell. The JDBC driver which you used there is completely outdated and deprecated. The way how you registered the driver is clumsy. That the DB connection is not closed in finally is prone to resource leaking. Okay, I'll stop...

I presume that you are getting an IllegalStateException because you are calling getWriter() and getOutputStream() on the same response. Which you're not allowed to do.

Related

<error-page> is not working for servlet

when exception in servlet then is not working but for jsp its work properly
web.xml code
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
servlet code
protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
{
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
/*
* TODO output your page here. You may use following sample code.
*/
String a=null;
a.toString();//this line will throw exception
}
finally {
out.close();
}
}
it does not redirect to error.jsp
Servlet code
this will throw the exception to the general error page
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
/*
* TODO output your page here. You may use following sample code.
*/
String a=null;
a.toString();
}
catch(Exception e)
{
throw new ServletException(e);
}
finally {
//dont write out.close();
}
}
when we write catch block in servlet it does not work and when we does not write catch block its work properly.
Servlet Code
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
DAL db=null;
ResultSet rs=null;
parameter p1=new parameter();
// Object param[];
// List<Object> param=new ArrayList<Object>();
long myId=0;
try {
db=new DAL();
String name=request.getParameter("fn");
db.setQuery("{call usp_StudentInsertData(?,?)}");
db.setInParam(1,name);
db.setInParam(2,1000);
db.insertUpdate();
out.println("insert");
response.sendRedirect("home.jsp");
}
catch(Exception e)
{
}
finally {
}
}

Jasper Report integration in Primefaces

I am posting a code snippet which worked well on other forms to print Jasperreport as Pdf.
<p:commandButton id="cmdPrint" value="Print"
actionListener="#{receiptMB.print()}"
disabled="#{receiptMB.chkSave == false}" process="#this" />
Backing Bean code snippet :
public void print(){
try
{
JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(getObjPrintList());
String reportPath= FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/Receipt.jasper");
JasperPrint jasperPrint=JasperFillManager.fillReport(reportPath,getReportParameters(), beanCollectionDataSource);
HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
httpServletResponse.setContentType("application / pdf");
httpServletResponse.addHeader("Content-disposition", "inline; filename=Receipt_" +objPrint.getDateNp()+".pdf");
ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
servletOutputStream.write(JasperExportManager.exportReportToPdf(jasperPrint));
servletOutputStream.flush();
servletOutputStream.close();
FacesContext.getCurrentInstance().renderResponse();
FacesContext.getCurrentInstance().responseComplete();
}
catch(JRException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The above code is working well on other forms but it is not working in a particular form which is a Dialog.It gives no error but, also it doesn't give any output.
I went around with some solutions but no work.

Using JResultSetDataSource in servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/pdf");
ServletOutputStream servletOutputstream = response.getOutputStream();
InputStream reportStream = getServletConfig().getServletContext().
getResourceAsStream("/report-src/Payment.jasper");
/* Here I am checking whether I am getting refrence of .jasper as
stream or not*/
System.out.println(reportStream);
try {
// Here i am establishing connection with database
Connection connection = Dbconn.getConnection();
Statement stmt = connection.createStatement();
/* Here I am fetching values using resultset with query
as I want to give the condition in where clause. At this servlet
which will be decided on the basis of request comes on this servlet
so I am using object of this resultset and will pass it as
parameter in the constructor of JRResultSetData */
ResultSet rset = stmt.executeQuery(query);
JRResultSetDataSource datasource = new JRResultSetDataSource(rset);
/* In this while loop I am checking whether I am getting
values in ResultSet */
while (rset.next()) {
System.out.println(rset.getString(2));
}
/* Here is the main problem as I think because I am passing object
of JRResultSet and passing this object in method to generate the report
in pdf format */
JasperRunManager.runReportToPdfStream(reportStream, servletOutputstream,
new HashMap(), datasource);
servletOutputstream.flush();
servletOutputstream.close();
} catch (Exception e) {
// display stack trace in the browser
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
response.setContentType("text/plain");
response.getOutputStream().print(stringWriter.toString());
}
}
Now nothing is being getting on report. I am not getting any error also. Even static data on report also not appearing on report. Only empty document is being generated.
I have wasted a lot of time on this, please help me.

Render a pdf stream on a jsp using struts2

I am using struts2 in my web application. I want to render a pdf stream on a jsp. i am currently doing this:
public String renderPDF() throws Exception
{
myService.rederPDF(getServletResponse().getServletOutputStream());
return SUCCESS;
}
The rederPDF method of myService gets a pdf stream and writes to the servlet response output stream. But this throws an exception that "The response has already been committed".
This exception occurs when you already sent some thing to client before you forward.
I am using Servlets for downloading files. Have a look.
public class FileDownloadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
byte[] b = null;
ServletOutputStream sop = null;
try {
response.setContentType("application/pdf");
response.setHeader("Content-Disposition","attachment; filename=yourFileName.pdf");
sop = response.getOutputStream();
b = myService.getFileData(); /* your code */
sop.write(b);
return;
} catch (Exception e) {
/* some code*/
}
finally{
/* some code*/
}
}
}

Why does response.getWriter() throw a checked exception?

How would an IOException be thrown in below code ? Is it if the response object times out ?
public void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
response.getWriter().print("Test");
} catch (IOException e) {
e.printStackTrace();
}
}
You are trying to write to a socket, so there could be all sorts of IO errors. The socket could have been closed / reset for example.
getWriter() javadoc
"IOException - if an input or output exception occurred"
In short, getWriter is an input/output operation which tries to open a PrintWriter (I believe). The opening of that writer can simply fail, resulting in the IOException thrown.
Plus, the print() operation is also input/output, so that goes by the same conditions.

Categories