简体   繁体   English

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

[英]The Jasper Reports servlet stopped working after calling response.getOutputStream()

I have code such as below. 我有如下代码。 The program stopped working at line servletOutputStream = response.getOutputStream(); 程序在servletOutputStream = response.getOutputStream();servletOutputStream = response.getOutputStream();停止工作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. 您将从响应中同时获取WriterOutputStream This is not allowed. 这是不允许的。 Read their javadocs: 阅读他们的javadocs:

getOutputStream() 的getOutputStream()

 ServletOutputStream getOutputStream() throws java.io.IOException 

Returns a ServletOutputStream suitable for writing binary data in the response. 返回适合于在响应中写入二进制数据的ServletOutputStream The servlet container does not encode the binary data. Servlet容器不对二进制数据进行编码。

Calling flush() on the ServletOutputStream commits the response. ServletOutputStream上调用flush()提交响应。 Either this method or getWriter() may be called to write the body, not both. 可以调用此方法或getWriter()来编写正文,而不能同时调用两者。

and

getWriter() 的getWriter()

 java.io.PrintWriter getWriter() throws java.io.IOException 

Returns a PrintWriter object that can send character text to the client. 返回一个PrintWriter对象,该对象可以将字符文本发送到客户端。 The PrintWriter uses the character encoding returned by getCharacterEncoding() . PrintWriter使用getCharacterEncoding()返回的字符编码。 If the response's character encoding has not been specified as described in getCharacterEncoding (ie, the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1. 如果未按照getCharacterEncoding描述指定响应的字符编码(即该方法仅返回默认值ISO-8859-1),则getWriter会将其更新为ISO-8859-1。

Calling flush() on the PrintWriter commits the response. PrintWriter上调用flush()提交响应。

Either this method or getOutputStream() may be called to write the body, not both. 可以调用此方法或getOutputStream()来编写主体,但不能同时调用两者。

(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. 您正在尝试在HTML响应中的这些HTML标签之间内联Jasper报告的PDF结果。 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. 您需要以这种方式重写servlet,以便它返回PDF,而不返回HTML噪音。 You should move all that HTML out the servlet into some JSP file. 您应该将所有HTML移出servlet到某个JSP文件中。 Then, you can call that servlet by a simple download link in the JSP 然后,您可以通过JSP中的简单下载链接来调用该servlet。

<a href="yourServletUrl">Download PDF</a>

or inside an <iframe> (yes, in JSP) 或在<iframe>内部(是,在JSP中)

<iframe src="yourServletUrl" style="width: 500px; height: 300px;"></iframe>

or in an <object> (also here, just in JSP) 或在<object> (也在这里,仅在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. 只需将HTML放在JSP页面中,在浏览器中打开JSP,然后网络浏览器就会注意将调用servlet,并以您期望的方式表示PDF。

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. 顺便说一下,您的doGet()doPost()都做的完全一样,这也是一种设计异味。 The JDBC driver which you used there is completely outdated and deprecated. 您在那里使用的JDBC驱动程序已完全过时和过时。 The way how you registered the driver is clumsy. 您注册驱动程序的方式很笨拙。 That the DB connection is not closed in finally is prone to resource leaking. finally数据库连接未关闭很容易导致资源泄漏。 Okay, I'll stop... 好吧,我停止...

I presume that you are getting an IllegalStateException because you are calling getWriter() and getOutputStream() on the same response. 我假设您收到一个IllegalStateException因为您在同一响应上调用getWriter()getOutputStream() Which you're not allowed to do. 您不允许这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 最佳做法response.getOutputStream - best practice response.getOutputStream response.getOutputStream已被调用 - response.getOutputStream has already been called 确保已收到`response.getOutputStream()。write()` - make sure `response.getOutputStream().write()` was received 我应该通过response.getOutputStream()显式关闭ZipOutputStream吗? - Should I explicitly close ZipOutputStream over response.getOutputStream()? PdfWriter.getInstance(document,response.getOutputStream())的等效项是什么? 脱颖而出 - what is equivalent for PdfWriter.getInstance(document,response.getOutputStream()); to excel 在JSP中将MySQL请求抛出IllegalStateException时使用的response.getOutputStream - response.getOutputStream used on MySQL request throwing IllegalStateException in JSP 第一次调用时response.getOutputStream()抛出IllegalStateException - response.getOutputStream() throws IllegalStateException when called for the first time 无法让getOutputStream()在servlet中工作 - Not able to get getOutputStream() working in servlet Jasper Reports:字体扩展不起作用 - Jasper Reports: Font extension not working 在第二个servlet请求中已经对此响应调用了getOutputStream() - getOutputStream() has already been called for this response on second servlet request
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM