[英]The Jasper Reports servlet stopped working after calling response.getOutputStream()
我有如下代碼。 程序在servletOutputStream = response.getOutputStream();
行servletOutputStream = response.getOutputStream();
停止工作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
。 這是不允許的。 閱讀他們的javadocs:
的getOutputStream()
ServletOutputStream getOutputStream() throws java.io.IOException
返回適合於在響應中寫入二進制數據的
ServletOutputStream
。 Servlet容器不對二進制數據進行編碼。在
ServletOutputStream
上調用flush()
提交響應。 可以調用此方法或getWriter()
來編寫正文,而不能同時調用兩者。
和
的getWriter()
java.io.PrintWriter getWriter() throws java.io.IOException
返回一個
PrintWriter
對象,該對象可以將字符文本發送到客戶端。PrintWriter
使用getCharacterEncoding()
返回的字符編碼。 如果未按照getCharacterEncoding
描述指定響應的字符編碼(即該方法僅返回默認值ISO-8859-1),則getWriter
會將其更新為ISO-8859-1。在
PrintWriter
上調用flush()
提交響應。可以調用此方法或
getOutputStream()
來編寫主體,但不能同時調用兩者。
(強調我的)
問題在您的特定情況下卻更大。 您正在嘗試在HTML響應中的這些HTML標簽之間內聯Jasper報告的PDF結果。 我不確定您在編寫代碼時的想法或想法,但這絕對是行不通的。 您需要以這種方式重寫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,然后網絡瀏覽器就會注意將調用servlet,並以您期望的方式表示PDF。
您的另一個問題是異常處理不是很好。 由於未重置響應緩沖區,因此您將完全看不到任何東西。 您應該改為
} catch (Exception e) {
throw new ServletException("descriptive message here", e);
}
因為容器完全知道如何處理異常。
順便說一下,您的doGet()
和doPost()
都做的完全一樣,這也是一種設計異味。 您在那里使用的JDBC驅動程序已完全過時和過時。 您注冊驅動程序的方式很笨拙。 finally
數據庫連接未關閉很容易導致資源泄漏。 好吧,我停止...
我假設您收到一個IllegalStateException
因為您在同一響應上調用getWriter()
和getOutputStream()
。 您不允許這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.