2012-05-10 4 views
0

私は奇妙な問題に遭遇しました。私は、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

+0

正確な例外を知るためにstackTraceをcatch節に表示します。 – Rakesh

+0

「getWriterまたはgetOutputStreamのどちらかを呼び出して本文を書き込むことはできますが、両方を読み込むことはできません」というドキュメントがあります。あなたはすでに 'getWriter'を呼び出しています。したがって、おそらく不正な状態の例外ですが、すべての例外情報を飲み込んでしまいます。 –

+0

@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

答えて

0

同じ応答内でresponse.getWriter()とresponse.getOutputStream()を呼び出すことはできません。コール

PrintWriter out = res.getWriter(); 

は、すでにあなたが例外を取得

ServletOutputStream outStream = res.getOutputStream(); 

を呼び出すときに、いわば応答を「主張」しています。

+0

ありがとうございます。あなたとDave Newtonはどちらも正しいですが、私は両方を使用できない場合、テキストと写真の両方をどのように印刷しますか? – blobs

+0

Daveの最後のコメントはあなたの問題の解決策になります。サーブレットは、JSPが表示するデータを準備する必要があります。あなたはフォーラム投稿を表すクラスを作成することができます。サーブレットはそのクラスのオブジェクトを作成し、そのクラスを使用してページにデータを表示できるJSPにリダイレクトします。 – ChadNC

関連する問題