2009-05-22 3 views
6

Ho un servlet che restituisce un file csv che sta "funzionando" su HTTP sia in Internet Explorer che in Firefox. Quando eseguo lo stesso servlet su HTTPS, solo firefox continua a scaricare il file csv su HTTPS. Non credo che questo sia necessariamente un Internet 6 o 7 problema descritto on MSDN:Restituzione del file CSV da Servlet utilizzando ServletOutputStream su HTTPS in Internet Explorer

Il messaggio è:

Internet Explorer non può scaricare data.csv da mydomain.com Internet Explorer non è stato in grado di apri questo sito Internet . Il sito richiesto è o non disponibile o non può essere trovato. Per favore riprova più tardi.

Si prega di notare che il sito è ancora 'su' dopo questo messaggio e si può continuare a navigare nel sito, è solo il download del CSV che richiede questo messaggio. Sono stato in grado di accedere a file simili su https su IE da altre applicazioni j2ee quindi credo che sia il nostro codice. Non dovremmo chiudere il bufferedOutputStream?

UPDATE

se chiudere o non chiudere il flusso di uscita: Ho fatto questa domanda sul forum di java posse e il discussion c'è anche penetranti. Alla fine sembra che nessun contenitore debba fare affidamento sul "client" (il proprio codice servlet in questo caso) per chiudere questo flusso di output. Pertanto, se l'errore di chiusura del flusso nel servlet provoca un problema, è più un riflesso della scarsa implementazione del contenitore servlet rispetto al codice. Ho posizionato il comportamento degli IDE e dei tutorial da Sun, Oracle e BEA e il modo in cui sono anche incoerenti nel fatto che chiudano il flusso o meno.

Chi IE comportamento specifico: Nel nostro caso un prodotto separato 'Oracle Web Cache' stava introducendo i valori di intestazione addizionali che explorer impatti Internet solo a causa del modo in cui IE implementa il requisito 'No Cache' (see the MSDN article). Il codice è:

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 funziona. Puoi descrivere cosa succede a IE? Non ottieni niente, si blocca, il file è troncato, ...? – erickson

+0

L'articolo MSDN evidenzia il messaggio. Aggiornerò la domanda a breve con il messaggio –

risposta

4

Sono molto confuso circa il vostro "dal retro attraverso il seno nella testa" meccanismo di scrittura. Perché non semplice (il flusso di output servlet sarà bufferend, questo è roba contenitore):

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); 

Ci dovrebbe essere anche senza bisogno di svuotare il flusso di output né per chiudere.

Il contenuto dell'intestazione non deve essere analizzato con maiuscole e minuscole da IE, ma chissà: non cammello fileName. La prossima domanda è la codifica. CSV è testo, quindi è necessario utilizzare getWriter() o g etOutputStream() e impostare il tipo di contenuto su "text/csv; charset = UTF-8", ad esempio. Ma il dao dovrebbe fornire il CSV come Stringa invece di byte [].

Il codice servlet non ha niente d con HTTPS, quindi il protocollo non ha importanza dal lato server. Potresti testare il servlet da localhost con HTTP spero.

E i filtri nella vostra applicazione? Ad esempio, un filtro può impostare un'intestazione HTTP (o come footer) con il controllo della cache.

+0

Funziona in HTTP e HTTPS nella maggior parte dei browser ad eccezione di Internet Explorer con HTTPS (stesso messaggio indicato nell'articolo MSDN a cui mi sono collegato). Ho notato che nel tuo esempio non stai facendo un out.close(). Sto cercando la conferma che il Servlet non dovrebbe chiamare anche out.close(). –

+0

Sono d'accordo che il materiale con IO bufferizzato non è necessario. Non farlo. Allo stesso modo, non penso che la chiusura del flusso sia necessaria. – jsight