[英]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. 我正在尝试创建一个网站,该网站通过从MySQL服务器检索和显示数据来动态创建“论坛线程”式的页面。 This data can be of two types: Plain text or an image file (stored as a BLOB). 此数据可以有两种类型:纯文本或图像文件(存储为BLOB)。 At the time of testing, we have 3 entries in the database - 1 text, 1 picture, 1 text. 在测试时,数据库中有3个条目-1个文本,1个图片,1个文本。 We are using JSP and servlets to retrieve and display the data. 我们正在使用JSP和servlet检索和显示数据。 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. 文本条目写得很好,但是当尝试显示图片时,我们不断从OutputStream实例获取IllegalStateExceptions-即,它将一直运行代码,直到我们尝试实例化OutputStream,然后抛出异常。
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. 我应该提到,如果我们尝试将代码的“ get-image”部分作为单独的servlet而不是JSP的一部分来运行,则它会很好地显示图像。
The servlet code looks as follows: Servlet代码如下所示:
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. 因为我们有3个ConversationID为587的条目。Content1是文本,Content2是BLOBS。
Any ideas or corrections would be much appreciated. 任何想法或纠正将不胜感激。 Thank you :D 谢谢:D
You can't call response.getWriter() and response.getOutputStream() within the same response. 您不能在同一响应中调用response.getWriter()和response.getOutputStream()。 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. 你会得到例外。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.