2009-05-22 16 views
6

Internet ExplorerとFirefoxの両方でHTTP経由でcsvファイルを返すサーブレットがあります。私がHTTPS上で同じサーブレットを実行する場合、FirefoxはHTTPS経由でCSVファイルをダウンロードし続けます。私は、これは、インターネット6または7問題がon MSDNを説明必ずしもあるとは思わない:Internet ExplorerでServletOutputStreamを使用してServletOutputStreamを使用してCSVファイルを返す

メッセージがある:Internet Explorerはmydomain.comインターネット エクスプローラから data.csvをダウンロードすることができません

がすることができませんでしたこの インターネットサイトを開きます。要求されたサイトは で、利用できないか、見つからないことがあります。 後でもう一度お試しください。

このメッセージの後にサイトはまだ「アップ」していますので、このメッセージを表示するCSVのダウンロードだけでサイトを閲覧することができます。他のj2eeアプリケーションからIE上のhttpsを介して同様のファイルにアクセスすることができましたので、私たちのコードだと思います。 bufferedOutputStreamを閉じるべきではないでしょうか?

出力ストリームをクローズするクローズするか否かUPDATE

私は、Javaの捜索隊フォーラムでこの質問をしてdiscussionも、洞察力があります。最終的には、この出力ストリームを閉じるためにコンテナが 'クライアント'(この場合はサーブレットコード)に依存する必要はありません。サーブレットのストリームを閉じるのに失敗した場合、問題が発生した場合は、サーブレットコンテナの実装がコードよりも劣っていることが反映されます。私は、Sun、Oracle、BEAのIDEとTutortialsの動作と、ストリームを閉じるかどうかにどのように矛盾があるのか​​を決めました。 IE固有の動作について

:私たちの場合は別の製品「Oracle Web Cacheは」唯一の方法のためIEは「いいえキャッシュ]要件(see the MSDN article)を実装している影響を与えるインターネットエクスプローラ追加のヘッダー値を導入しました。 コードは次のとおりです。

public class DownloadServlet extends HttpServlet { 
    public void doGet(HttpServletRequest request, 
         HttpServletResponse response) throws ServletException, 
                  IOException { 
     ServletOutputStream out = null; 
     ByteArrayInputStream byteArrayInputStream = null; 
     BufferedOutputStream bufferedOutputStream = null; 
     try { 
      response.setContentType("text/csv"); 
         String disposition = "attachment; fileName=data.csv"; 
      response.setHeader("Content-Disposition", disposition); 

      out = response.getOutputStream(); 
      byte[] blobData = dao.getCSV(); 

      //setup the input as the blob to write out to the client 
      byteArrayInputStream = new ByteArrayInputStream(blobData); 
      bufferedOutputStream = new BufferedOutputStream(out); 
      int length = blobData.length; 
      response.setContentLength(length); 
      //byte[] buff = new byte[length]; 
      byte[] buff = new byte[(1024 * 1024) * 2]; 

      //now lets shove the data down 
      int bytesRead; 
      // Simple read/write loop. 
      while (-1 != 
        (bytesRead = byteArrayInputStream.read(buff, 0, buff.length))) { 
       bufferedOutputStream.write(buff, 0, bytesRead); 
      } 
      out.flush(); 
      out.close(); 

     } catch (Exception e) { 
      System.err.println(e); throw e; 

     } finally { 
      if (out != null) 
       out.close(); 
      if (byteArrayInputStream != null) { 
       byteArrayInputStream.close(); 
      } 
      if (bufferedOutputStream != null) { 
       bufferedOutputStream.close(); 
      } 
     } 
    } 
+0

Firefoxが動作します。 IEに何が起こるか説明できますか?あなたは何も手に入れませんか、ハングアップしますか、ファイルは切り捨てられますか? – erickson

+0

MSDNの記事でメッセージが強調表示されています。私はすぐにメッセージで質問を更新します。 –

答えて

4

私はあなたの書き込みメカニズム「後ろから胸を通して頭に」については本当に混乱しています。なぜ簡単ではありません(サーブレット出力ストリームがbufferendされ、コンテナのもののthats):

byte[] csv = dao.getCSV(); 
response.setContentType("text/csv"); 
response.setHeader("Content-Disposition", "attachment; filename=data.csv")); 
reponse.setContentLength(csv.length); 
ServletOutputStream out = response.getOutputStream(); 
out.write(csv); 

また、出力ストリームをフラッシュするも閉鎖する必要はありません。

ヘッダーの内容をIEで大文字と小文字を区別する必要はありませんが、キャメラケースfileNameを知っている人は分かりません。次の質問はエンコーディングです。 CSVはテキストなので、代わりにgetWriter(を使用するか、g etOutputStream()を使用し、コンテンツタイプを "text/csv; charset = UTF-8"に設定してください)。しかし、daoは、バイト[]の代わりに文字列としてCSVを提供する必要があります。

サーブレットコードはHTTPSで何もしないので、プロトコルはサーバー側からは問題ありません。あなたはHTTPを使ってlocalhostからサーブレットをテストすることができます。

アプリケーションのフィルタはどうですか?フィルタは、たとえば、キャッシュ制御を使用してHTTPヘッダー(またはフッター)を設定することもできます。

+0

HTTPSを使用しているInternet Explorer(リンク先のMSDNの記事に示されているのと同じメッセージ)を除いて、ほとんどのブラウザではHTTPとHTTPSで動作します。 あなたの例では、out.close()を実行していないことに注意してください。サーブレットがout.close()を呼び出してはならないという確認を探しています。 –

+0

私はバッファされたIOのものは不要であることに同意します。それをしないでください。同様に、私はストリームを閉じることが必要だとは思わない。 – jsight

関連する問題