response.getOutputStream used on MySQL request throwing IllegalStateException in JSP
Hello Java Forums,
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 - i.e., 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:
Code:
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 3x "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
Re: response.getOutputStream used on MySQL request throwing IllegalStateException in
I'd highly recommend reviewing the API for the Classes and methods you are using...to quote the API for ServletResponse (Java EE 6 ) method getOutputStream:
Quote:
Throws:
IllegalStateException - if the getWriter method has been called on this response
And another tip: read the overview of Statement (Java Platform SE 6)
Re: response.getOutputStream used on MySQL request throwing IllegalStateException in
You also can't send the image and the Html at the same time.
They are two different things as far as the browser is concerned.
An image is returned from a request made when an <img> tag is encountered.
The usual solution (and one you seem to have come close to) is to use an <img> tag containing a url to an image servlet, with an id identifying the image to return.
That servlet will then stream the image via the response stream (as above).