Downloading file with Response
imrehajagos Apr 29, 2010 11:19 AMHello to everybody,
I tried to ported a Seam Web Project to JBP 2.7.2, then to GateIn 3.0.0. I solved lot of problems, but unfortunatelly some functionalities still broken, for example the file downloader part. The application works fine as native seam application, so I click on the download button, then a file choser window appears, after that I can save my file to the proper place, but in JBP or GateIn, when I try to download a file - a pdf or an xml - it just shows the file content in the web browser as output.
I use a h:commandButton to firing the action and in this case the GateIn gives back an ActionResponseImpl - org.gatein.pc.portlet.impl.jsr168.api.ActionResponseImpl or org.jboss.portal.portlet.impl.jsr168.api.ActionResponseImpl, it depends from GateIn or JBP. I tried with a4j:commandButton also and in that case the GateIn gives back a BufferedResourceResponseWrapper, JBP gives a BufferedRenderResponseWrapper.
I give up the a4j case, when I read somewhere there is no way to save file with response via ajax because of the portlet specification.
Here is a sample function:
public void downloadFile() throws IOException {
String filePath = null;
String fileName = null;
int read = 0;
byte[] bytes = new byte[DEFAULT_BUFFER_SIZE];
Object responseObject = FacesContext.getCurrentInstance().getExternalContext().getResponse();
// native seam
if (responseObject instanceof HttpServletResponse) {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
ELContext el = facesContext.getELContext();
Application app = facesContext.getApplication();
ExpressionFactory ef = app.getExpressionFactory();
ValueExpression pathVe = ef.createValueExpression(el, "#{knowledgebasefile.knowledgeBaseFilePath}", String.class);
filePath = (String) pathVe.getValue(el);
int extDot = filePath.lastIndexOf(File.separator);
fileName = filePath.substring(extDot + 1);
ValueExpression mimeVe = ef.createValueExpression(el, "#{knowledgebasefile.mimeType}", String.class);
response.setContentType(mimeVe.getValue(el).toString());
response.addHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
try {
ServletOutputStream os = response.getOutputStream();
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
while ((read = fis.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
} catch (Exception e) {
System.err.println(e);
}
facesContext.responseComplete();
// in GateIn
} else if (responseObject instanceof ActionResponseImpl) {
log.info("response is ActionResponseImpl");
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
ActionResponseImpl portalResponse = (ActionResponseImpl) externalContext.getResponse();
HttpServletResponseWrapper response = portalResponse.getRealResponse();
ELContext el = facesContext.getELContext();
Application app = facesContext.getApplication();
ExpressionFactory ef = app.getExpressionFactory();
ValueExpression pathVe = ef.createValueExpression(el, "#{knowledgebasefile.knowledgeBaseFilePath}", String.class);
filePath = (String) pathVe.getValue(el);
int extDot = filePath.lastIndexOf(File.separator);
fileName = filePath.substring(extDot + 1);
ValueExpression mimeVe = ef.createValueExpression(el, "#{knowledgebasefile.mimeType}", String.class);
response.setContentType(mimeVe.getValue(el).toString());
response.addHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
try {
ServletOutputStream os = response.getOutputStream();
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
while ((read = fis.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
} catch (Exception e) {
System.err.println(e);
}
} else {
log.info("fail to download - unexpected response type");
log.info("response instance of: " + responseObject.getClass().getName());
}
}
Here it is the a4j try:
BufferedResourceResponseWrapper portalResponse = (BufferedResourceResponseWrapper) responseObject;
RenderResponseImpl responseRRI = (RenderResponseImpl) portalResponse.getResponse();
HttpServletResponseWrapper response = responseRRI.getRealResponse();
I used the following versions:
GateIn 3.0.0.GA
Seam 2.2.0.GA
Portlet Bridge 2.0.0.CR1
RichFaces 3.3.3.CR1
Thanks for your help and sorry for my English.
Regards,
Imre