繁体   English   中英

调用response.getOutputStream()之后,Jasper Reports servlet停止工作。

[英]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();

您将从响应中同时获取WriterOutputStream 这是不允许的。 阅读他们的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM