Ciao a tutti, ho realizzato una servlet Java per la creazione di un file.
Ora però non so come fare scaricare all'utente il file creato.
Sapreste darmi qualche dritta su come poter far fare il download ?
Grazie!
Ciao a tutti, ho realizzato una servlet Java per la creazione di un file.
Ora però non so come fare scaricare all'utente il file creato.
Sapreste darmi qualche dritta su come poter far fare il download ?
Grazie!
Dove è posizionato il file rispetto alla web application?
La soluzione è avere un'altra servlet che si occupa del download del file. Il principio basilare è che basta ottenere un InputStream del file e poi leggere a blocchi di byte e buttarli pari-pari sul OutputStream (il ServletOutputStream della response, che è-un OutputStream).
Però bisogna anche settare degli header in modo appropriato. Sicuramente il Content-Type affinché un client possa dedurre come trattare il documento. Se vuoi che qualunque browser faccia il download senza sapere altro, si può usare il content type "application/octet-stream".
Poi visto che è un file e sai a priori la lunghezza, sarebbe anche utile ed appropriato impostare il header Content-Length.
Si può anche impostare il Content-Disposition per indicare che è un attachment con un certo nome specifico.
Poi si possono facoltativamente impostare altri header per permettere o impedire il caching.
Per lo streaming si possono anche usare metodi di librerie apposite come la Apache Commons IO che ha una classe FileUtils con un comodissimo metodo public static long copyFile(File input, OutputStream output)
Ultima modifica di andbin; 25-11-2016 a 10:34
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Ciao, il file di cui voglio fare il download è un file Excel creato con la libreria Apache POI, non mi interessa memorizzarlo su server.
Ma non funziona.codice:response.setContentType( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment; filename=excel.xlsx"); OutputStream out = response.getOutputStream(); workbook.write(out); workbook.close(); out.flush(); out.close();
Innanzitutto l'OutputStream che ottieni dalla response non va chiuso. Quell'OutputStream è gestito dall'Application Server / Servlet Container, è lui che si deve occupare della chiusura.
Poi dici che non funziona: controlla i log per vedere se vi è qualche eccezione ed, eventualmente, postala qui. Al di là del content-type (che io imposto solitamente a "application/octet-stream;name=...") non vedo problemi nel codice che hai postato.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
Il problema può essere il fatto di non aver inviato il Content-Length, perlomeno con certi browser ci potrebbe essere.
Quindi:
- scarichi il documento su un file temporaneo, poi sapendo la lunghezza invii il Content-Length e poi fai lo streaming in output del file.
oppure
- scarichi il documento in memoria su un ByteArrayOutputStream, poi sapendo la lunghezza invii il Content-Length e poi fai lo streaming in output del ByteArrayOutputStream usando il suo writeTo(OutputStream out).
A tua scelta ....![]()
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Ok, non ho chiuso l'OutputStream ed ho impostato il content-type ad "application/octet-stream".
Il log mi da solo "Inizializzazione riuscita", ma nulla ancora non riesco dal browser ad effettuare il download del file che ho scritto.
Ho provato la seconda strada scrivendo questo codice:
ma ancora nulla!! il file testxls.xls no ne vuole sapere di essere scaricatocodice:ByteArrayOutputStream outByteStream = new ByteArrayOutputStream(); workbook.write(outByteStream); byte [] outArray = outByteStream.toByteArray(); response.setContentType( "application/OCTET-STREAM"); response.setContentLength(outArray. length); response.setHeader( "Expires:", "0"); response.setHeader( "Content-Disposition", "attachment; filename=testxls.xls"); OutputStream outStream = response.getOutputStream(); outStream.write(outArray); outStream.flush();
?
Non sto parlando dell'eventuale console dell'ambiente di sviluppo, ma del log del tuo Servlet Container (Tomcat) o del tuo Application Server dove gira la webapp. Ad esempio, Tomcat ha diversi file di log: un file dove logga tutti gli accessi, un file dove logga lo standard output, un file dove logga lo standard error (ed è qui che finiscono le eccezioni), un log di catalina, ecc...
Vedi anche la risposta di andbin.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
Di per sé NON serve ottenere un nuovo byte[] array ... semplicemente è uno spreco di risorse. ByteArrayOutputStream ha size() e il writeTo(OutputStream out) citato prima.
Ma a parte lo "spreco" di memoria, non vedo nulla di palesemente/grossolanamente errato.
nulla in che senso?
- la response è completamente vuota o c'è qualcosa?
- se c'è qualcosa che cosa è? (analizzalo con un hex editor/viewer, eventualmente)
- c'è qualche eccezione?
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet
Con nulla intendo che non succede nulla la response non restituisce nessun valore.
Chiamo la servlet mediante questa chiamata Ajax:
e aimè , non viene visualizzata nessuna finestra di alert.codice:$.ajax({ url : "CreaFileExcel", type : "POST", data : {path:$( "#input_file").val()}, async: false, dataType : "json", processData: false, contentType: false, success: function(msg) { if(msg.esito!=null ) alert("Creato file Log_Errori.xlsx"); }, error: function (jqXHR, textStatus, errorThrown) { alert("KO"); } });
Nella console non ho eccezioni e sul server non ho ancora trovalo il file di log dei messaggi di errore.