简体   繁体   中英

response.getOutputStream used on MySQL request throwing IllegalStateException in JSP

I'm faced with what I find to be an odd problem. I'm trying to create a website that dynamically creates a "forum-thread"-ish page by retrieving and displaying data from a MySQL server. This data can be of two types: Plain text or an image file (stored as a BLOB). At the time of testing, we have 3 entries in the database - 1 text, 1 picture, 1 text. We are using JSP and servlets to retrieve and display the data. The text entries are written just fine, but when trying to display the pictures, we keep getting IllegalStateExceptions from our OutputStream instance - ie, it will run the code up until we try to instantiate the OutputStream, and then throw the exception.

We figured it has something to do with multithreading, but after trying using synchronized and specific reentrantlocks, we still get the exception. I should mention, that if we try to run the "get-image" part of the code as a seperate servlet and not as part of the JSP, it displays the image just fine.

The servlet code looks as follows:

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class listConversation
 */
@WebServlet("/ListConversation")
public class ListConversation extends HttpServlet
{

    @Override
    protected synchronized void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        try
        {
            String connectionURL = [our database URL, username and password];
            String myDriver = "com.mysql.jdbc.Driver";

            Class.forName(myDriver).newInstance();

            Connection con = DriverManager.getConnection(connectionURL);

            Statement stmt = con.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT ID, Content1 FROM Conversations WHERE ConversationID=587 ORDER BY Date ASC");

            res.setContentType("text/html");
            PrintWriter out = res.getWriter();

            out.print("<hr>");

            while (rs.next())
            {
                out.print("<b>Besked</b><br/>" + rs.getString("Content1") + "<br/><br/>");

                try {

                    System.out.println("Try-block started.");
                    Statement stmt2 = con.createStatement();
                    System.out.println("Statement created.");
                    ResultSet rs2 = stmt2.executeQuery("SELECT Content2 FROM Conversations WHERE ID = 4");
                    System.out.println("Statement executed.");
                    ServletOutputStream outStream = res.getOutputStream();
                    System.out.println("Outputstream initialized.");
                    Blob image;
                            if (rs2.next()) {
                                image = rs2.getBlob(1);
                                System.out.println("Image created.");
                            } else {
                                res.setContentType("text/html");
                                out.println("h4><font color='red'>image not found for given id</font></h4>");
                                        return;
                            }
                            res.setContentType("image/gif");
                            InputStream in = image.getBinaryStream();
                            int length = (int) image.length();
                            int bufferSize = 1024;
                            byte[] buffer = new byte[bufferSize];
                            System.out.println("Initializing...");
                            while ((length = in.read(buffer)) != -1) {
                                outStream.write(buffer, 0, length);
                            }
                            System.out.println("Image streamed.");
                            in.close();
                            stmt2.close();
                            rs2.close();
                            outStream.close();
                            System.out.println("Closing.");
                            out.flush();
                }
                catch(IllegalStateException e)
                {
                    System.out.println("Darn OutputStreams...");
                }
                catch (Exception e) {
                    res.setContentType("text/html");
                    out.println("<h4><font color='red'>Image Display Error=" + e.getMessage() +
                            "</font></h4>");
                    return;
                }

                out.print("<hr>");
            }

            stmt.close();
            con.close();

            }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        doGet(req,res);
    }


}

The console output is:

Try-block started. 
Statement created. 
Statement executed.
Darn OutputStreams...

as we have three entries with the ConversationID of 587. Content1 is text, Content2 are BLOBS.

Any ideas or corrections would be much appreciated. Thank you :D

You can't call response.getWriter() and response.getOutputStream() within the same response. The call

PrintWriter out = res.getWriter();

has already "claimed" the response so to speak so when you call

ServletOutputStream outStream = res.getOutputStream();

you get the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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