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>");
开发者_StackOverflow中文版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 theServletOutputStream
commits the response. Either this method orgetWriter()
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. ThePrintWriter
uses the character encoding returned bygetCharacterEncoding()
. If the response's character encoding has not been specified as described ingetCharacterEncoding
(i.e., the method just returns the default value ISO-8859-1),getWriter
updates it to ISO-8859-1.Calling
flush()
on thePrintWriter
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
<a href="yourServletUrl">Download PDF</a>
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.
精彩评论