2009-05-22 20 views
6

我有一個Servlet,它返回一個csv文件,該文件在Internet Explorer和Firefox中通過HTTP工作。當我通過HTTPS執行相同的Servlet時,只有Firefox繼續通過HTTPS下載csv文件。我不認爲這一定是一個互聯網6或7問題描述on MSDN在Internet Explorer中使用ServletOutputStream通過HTTPS從Servlet中返回CSV文件

的消息是:

Internet Explorer無法從mydomain.com下載 data.csv互聯網 瀏覽器無法打開這個 互聯網網站。請求的網站是 無法找到或無法找到。 請稍後再試。

請注意,該網站在此消息之後仍處於「啓動」狀態,您可以繼續瀏覽網站,只需下載提示此消息的CSV即可。我已經能夠通過其他j2ee應用程序通過https訪問類似的文件,所以我相信這是我們的代碼。 我們是不是應該關閉bufferedOutputStream?

UPDATE

是否關閉或不關閉輸出流: 我問對java波塞論壇這個問題和discussion也有見地。最後,似乎沒有容器應該依賴「客戶端」(在這種情況下是您的servlet代碼)來關閉此輸出流。因此,如果您在servlet中關閉流失敗導致問題,那麼它就更多地反映了您的servlet容器的實現比您的代碼差。我選擇了Sun,Oracle和BEA的IDE和應用程序的行爲,以及它們是否在關閉流的方面不一致。

關於IE特定行爲:在我們的情況下,一個單獨的產品「Oracle Web緩存」被引入其影響的Internet Explorer只是因爲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 2009-05-22 20:36:25

+0

MSDN文章突出顯示了該消息。我會很快更新這個問題的消息。 – 2009-05-22 20:44:59

回答

4

我真搞不清楚你的「從後通過母乳進入頭」寫入機制。爲什麼不簡單(servlet的輸出流將bufferend,這就是容器的東西):

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解析大小寫,但誰知道:不要camelcase fileName。接下來的問題是編碼。 CSV是文本,因此您應該使用getWriter()或g etOutputStream(),並將內容類型設置爲「text/csv; charset = UTF-8」。但dao應提供CSV作爲字符串,而不是byte []。

servlet代碼與HTTPS沒有任何關係,所以協議在服務器端並不重要。我可以用HTTP來測試本地主機上的servlet。

你的應用程序中的過濾器怎麼樣?例如,一個過濾器可以設置一個HTTP頭(或作爲頁腳)與緩存控制。

相關問題