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.
}
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
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
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