2010-05-26 12 views

Respuesta

33

Establecer el encabezado HTTP Content-Disposition a attachment. Aparecerá un diálogo Guardar como. Puedes hacerlo usando HttpServletResponse#setHeader(). Puede obtener la respuesta del servlet HTTP desde debajo de los capós JSF al ExternalContext#getResponse().

En contexto JSF, solo necesita asegurarse de llamar al FacesContext#responseComplete() para evitar IllegalStateException s volando alrededor.

ejemplo Comienzo:

public void download() throws IOException { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse(); 

    response.reset(); // Some JSF component library or some Filter might have set some headers in the buffer beforehand. We want to get rid of them, else it may collide. 
    response.setContentType("application/xml"); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename. 
    response.setHeader("Content-disposition", "attachment; filename=\"name.xml\""); // The Save As popup magic is done here. You can give it any filename you want, this only won't work in MSIE, it will use current request URL as filename instead. 

    BufferedInputStream input = null; 
    BufferedOutputStream output = null; 

    try { 
     input = new BufferedInputStream(getYourXmlAsInputStream()); 
     output = new BufferedOutputStream(response.getOutputStream()); 

     byte[] buffer = new byte[10240]; 
     for (int length; (length = input.read(buffer)) > 0;) { 
      output.write(buffer, 0, length); 
     } 
    } finally { 
     close(output); 
     close(input); 
    } 

    facesContext.responseComplete(); // Important! Else JSF will attempt to render the response which obviously will fail since it's already written with a file and closed. 
} 
+0

muchas gracias de verdad. Puse el código y ahora, cuando hago clic en el enlace, el navegador (FF) reemplaza la página actual con una página que contiene el contenido del archivo en lugar de abrir una ventana de descarga. ¿Qué podría estar haciendo mal? – volvox

+1

Pruebe también en otros navegadores (IE, Chrome) o reinicie FF con un perfil limpio. Puede suceder que un navegador web esté configurado para ser la aplicación predeterminada para archivos XML y que los archivos XML se abran automáticamente cuando se descarguen. – BalusC

+1

Ah, también asegúrese de que no se trate de una solicitud asíncrona (ajaxical), sino simplemente de una solicitud síncrona ("plain vainilla"). Es decir. solo use 'h: commandLink' o' h: commandButton', pero no RichFaces, Ajax4jsf, IceFaces, etc. componentes 'UICommand' impulsados ​​por ájaxical. – BalusC

3

utilizar el encabezado HTTP content-disposition: attachment

0

A veces es necesario para forzar el escritor para enviar el contenido al cliente llamando response.getWriter().flush(); antes de cerrar el escritor. Esto provocó el guardado como ventana emergente en mi caso.

+1

Esto solo es necesario cuando la cadena de solicitud-respuesta contiene una implementación personalizada 'HttpServletResponseWrapper', que devuelve un escritor personalizado quebrado. Para las implementaciones estándar de Servlet y JSF esto no es absolutamente necesario. La solución debe ser corregir la implementación de envoltura/escritor y no vaciar manualmente el escritor en todas partes del código. – BalusC

Cuestiones relacionadas