2009-05-22 11 views
6

Tengo un servlet que devuelve un archivo csv que está 'funcionando' a través de HTTP en Internet Explorer y Firefox. Cuando ejecuto el mismo Servlet sobre HTTPS, solo firefox continúa descargando el archivo csv a través de HTTPS. No creo que esto es necesariamente una Internet 6 o 7 problema descrito on MSDN:Devolución de archivo CSV de Servlet utilizando ServletOutputStream a través de HTTPS en Internet Explorer

El mensaje es:

Internet Explorer no puede descargar data.csv de mydomain.com Internet Explorer no pudo abra este sitio de Internet . El sitio solicitado es ya sea no disponible o no se puede encontrar. Por favor, inténtelo de nuevo más tarde.

Tenga en cuenta que el sitio aún está 'activo' después de este mensaje y puede seguir navegando por el sitio, es solo la descarga del CSV que solicita este mensaje. He podido acceder a archivos similares a través de https en IE desde otras aplicaciones j2ee, así que creo que es nuestro código. ¿No deberíamos estar cerrando el bufferOutputStream?

ACTUALIZACIÓN

si cerrar o no cerrar la secuencia de salida: hice esta pregunta en los foros de Java Posse y el discussion también le puede ser útil. Al final parece que ningún contenedor debe confiar en el 'cliente' (su código de servlet en este caso) para cerrar este flujo de salida. Por lo tanto, si su falla al cerrar la secuencia en su servlet causa un problema, es más una reflexión sobre la pobre implementación de su contenedor de servlets que su código. Ubiqué el comportamiento de los IDEs y tutortials de Sun, Oracle y BEA y de la forma en que también son inconsistentes en cuanto a si cierran la transmisión o no.

Sobre el IE comportamiento específico: En nuestro caso un producto independiente 'Oracle Web Cache' fue la introducción de los valores de cabecera adicionales que el explorador impactos Internet sólo por la forma en IE implementa el 'No Cache' requisito (see the MSDN article). El código es:

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 funciona. ¿Puedes describir lo que le sucede a IE? ¿No obtienes nada, se cuelga, se trunca el archivo, ...? – erickson

+0

El artículo de MSDN resalta el mensaje. Voy a actualizar la pregunta en breve con el mensaje. –

Respuesta

4

estoy realmente confundido acerca de su "de vuelta a través del pecho en la cabeza" mecanismo de escritura. ¿Por qué no es sencillo (se bufferend el flujo de salida de servlets, eso es cosa de contenedores):

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

También debería haber ninguna necesidad de vaciar el flujo de salida ni a cerrar.

IE no debe analizar el contenido del encabezado, pero quién sabe: no haga el camelcase fileName. La siguiente pregunta es la codificación. CSV es texto, por lo que debe usar getWriter() en su lugar o g etOutputStream() y establecer el tipo de contenido como "text/csv; charset = UTF-8" por ejemplo. Pero el dao debe proporcionar el CSV como cadena en lugar de byte [].

El código de servlet no tiene nada que ver con HTTPS, por lo que el protocolo no importa desde el lado del servidor. Puede probar el servlet desde localhost con HTTP, espero.

¿Qué pasa con los filtros en su aplicación? Un filtro también puede establecer un encabezado HTTP (o como pie de página) con control de caché, por ejemplo.

+0

Funciona en HTTP y HTTPS en la mayoría de los navegadores, con la excepción de Internet Explorer con HTTPS (el mismo mensaje se indica en el artículo de MSDN al que me he vinculado). Noté en su ejemplo que no está haciendo un out.close(). Estoy buscando la confirmación de que el Servlet no debería estar llamando.close() también. –

+0

Acepto que las cosas con IO con búfer no son necesarias. No hagas eso. Del mismo modo, no creo que sea necesario cerrar la transmisión. – jsight

Cuestiones relacionadas