私は奇妙な問題に遭遇しました。私は、MySQLサーバからデータを取得して表示することによって、 "フォーラムスレッド"のページを動的に作成するWebサイトを作成しようとしています。このデータには、プレーンテキストまたはイメージファイル(BLOBとして格納)の2種類があります。テスト時には、データベースにテキストが1つ、画像が1つ、テキストが1つの3つのエントリがあります。 JSPとサーブレットを使用してデータを取得して表示しています。テキスト入力はうまく書かれていますが、画像を表示しようとすると、私たちはOutputStreamインスタンスからIllegalStateExceptionsを取得し続けます。つまり、OutputStreamをインスタンス化しようとするまでコードを実行して例外をスローします。MySQLリクエストでresponse.getOutputStreamが使用され、JSPでIllegalStateExceptionがスローされる
マルチスレッドとは関係がありますが、同期された特定のリエントラントロックを使用しようとすると、引き続き例外が発生します。 JSPの一部ではなく、別のサーブレットとしてコードの「取得イメージ」部分を実行しようとすると、イメージがうまく表示されます。次のように
サーブレットのコードが見えます:
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);
}
}
コンソール出力は次のようになります。
Try-block started.
Statement created.
Statement executed.
Darn OutputStreams...
我々は587 Content1のはconversationIdと3つのエントリを持っているようにテキストで、Content2はBLOBSです。
どのようなアイデアや修正があれば幸いです。ありがとうございました:D
正確な例外を知るためにstackTraceをcatch節に表示します。 – Rakesh
「getWriterまたはgetOutputStreamのどちらかを呼び出して本文を書き込むことはできますが、両方を読み込むことはできません」というドキュメントがあります。あなたはすでに 'getWriter'を呼び出しています。したがって、おそらく不正な状態の例外ですが、すべての例外情報を飲み込んでしまいます。 –
@Rakesh - 私たちは独自のデバッグ目的のためにsysoを追加しましたが、それがどのように役立つのか分かりません。 スタックトレースは次のようになります。 '試行ブロックが開始されました。 ステートメントが作成されました。 ステートメントが実行されました。 java.lang.IllegalStateException ダーンOutputStreams ... offentlig.ListConversation.doGetでorg.apache.jasper.runtime.ServletResponseWrapperInclude.getOutputStreamで \t(ServletResponseWrapperInclude.java:65) \t(ListConversation.java:59) \t (HttpServlet.java:722) .... ' – blobs