Boa Tarde,
Desenvolvi uma app web(JSF2.0 e PrimeFaces) que em determinada pagina o usuário pode fazer o download de um arquivo ZIP:
public String download(File arquivo, String tipo){
if(arquivo.exists()){
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
OutputStream os = null;
byte[] arquivoGerado= new ConverteArquivo().recuperaFileEmByte(arquivo);
try {
os = response.getOutputStream();
response.setContentType("application/"+tipo);
response.setContentLength(arquivoGerado.length);
response.setHeader("Content-disposition","attachment; filename="+arquivo.getName());
os.write(arquivoGerado);
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(os != null){
os.flush();
os.close();
}
facesContext.responseComplete();
} catch (IOException e) {
e.printStackTrace();
}
}
return "download.xhtml?faces-redirect=true";
}else{
return "arquivoNaoExiste.xhtml?faces-redirect=true";
}
}
Esse codigo usa o OutputStream, e ao ser executado ele me gera uma
java.lang.IllegalStateException: getOutputStream() has already been called for this response
Dei uma pesquisada e descobri que isso é gerado por causa do JSP que faz um getWriter() para mandar o texto html.
Por isso usei o PrintWriter:
public String download(File arquivo, String tipo){
if(arquivo.exists()){
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
OutputStream os = null;
//byte[] arquivoGerado= new ConverteArquivo().recuperaFileEmByte(arquivo);
try {
//os = response.getOutputStream();
response.setContentType("application/"+tipo);
//response.setContentLength(arquivoGerado.length);
response.setHeader("Content-disposition","attachment; filename="+arquivo.getName());
InputStream in = new FileInputStream(arquivo);
PrintWriter output = response.getWriter();
int bit = 256;
while ((bit) >= 0) {
bit = in.read();
output.write(bit);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(os != null){
os.flush();
os.close();
}
facesContext.responseComplete();
} catch (IOException e) {
System.out.println("2");
}
}
return "download.xhtml?faces-redirect=true";
}else{
return "arquivoNaoExiste.xhtml?faces-redirect=true";
}
Porem, esse codigo me gera uma:
java.net.SocketException: Software caused connection abort: socket write error
Ambos funcionam apesar das exceptions, porem qual seria uma solução mais elegante a ser usada nesse caso, o Output ou PrintWriter?
ps. Poderia ter usado o h:outputlink porem perderia a função de validar se o arquivo existe ou não.
Caso não tenha ficado muito claro a duvida posso tentar ilustrar de outra maneira
Desde ja agradeço