我有如下代码。程序在 servletOutputStream = response.getOutputStream();
行停止工作。我不知道如何解决这个问题?有人可以帮我解决这个问题吗?
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>
最佳答案
看这里:
PrintWriter out = response.getWriter();
// *snip*
servletOutputStream = response.getOutputStream();
您将两者 Writer
和OutputStream
从响应中。这是不允许的。阅读他们的 javadoc:
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.
和
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.
(强调我的)
问题是在你的具体情况下,但要大得多。您正在尝试将 Jasper Report 的 PDF 结果内联到 HTML 响应中的这些 HTML 标记之间。我不确定你在编写代码时的想法或想法,但这绝对行不通。您需要以这种方式重写 servlet,以便它仅返回 PDF,而不是一堆 HTML 噪音。您应该将所有 HTML 从 servlet 移出到某个 JSP 文件中。然后,您可以通过 JSP 中的简单下载链接来调用该 servlet
<a href="yourServletUrl">Download PDF</a>
或在 <iframe>
内(是的,在 JSP 中)
<iframe src="yourServletUrl" style="width: 500px; height: 300px;"></iframe>
或在<object>
中(也在这里,只是在 JSP 中)
<object data="yourServletUrl" type="application/pdf" width="500" height="300" />
只需将该 HTML 放入 JSP 页面中,在浏览器中打开 JSP,Web 浏览器就会负责调用 servlet,并且 PDF 将按照您想要的方式表示。
你的另一个问题是异常处理不是很好。由于响应缓冲区未重置,因此您将完全看不到任何内容。你应该做的是
} catch (Exception e) {
throw new ServletException("descriptive message here", e);
}
因为容器完全知道如何处理异常。
您的doGet()
和doPost()
正在做完全相同的事情,顺便说一下,还有一种设计的味道。您在那里使用的 JDBC 驱动程序已完全过时且已弃用。您注册驱动程序的方式很笨拙。 finally
中数据库连接未关闭很容易出现资源泄漏。好吧,我就停下来了……
关于java - Jasper Reports servlet 在调用 response.getOutputStream() 后停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7225367/