我已经完成以下工作:
现在,我需要执行步骤4:
谁能给我一个提示?我试图了解我在Google上发现的内容,但是它并没有达到预期的效果。我必须设置内容类型吗?当我设置应用程序/八位字节流时,只有txt和csv文件可以正确显示(在浏览器中,而不是我想要的下载弹出窗口),其他文件将无法工作…
JSP:
<a4j:commandLink value="Download" action="#{appController.downloadFile}" rendered="#{!file.directory}"> <f:param name="file" value="#{file.absoluteFilename}" /> </a4j:commandLink>
appController:
public String downloadFile() { String filename = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("file"); File file = new File(filename); HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); writeOutContent(response, file, file.getName()); FacesContext.getCurrentInstance().responseComplete(); return null; } private void writeOutContent(final HttpServletResponse res, final File content, final String theFilename) { if (content == null) { return; } try { res.setHeader("Pragma", "no-cache"); res.setDateHeader("Expires", 0); res.setHeader("Content-disposition", "attachment; filename=" + theFilename); FileInputStream fis = new FileInputStream(content); ServletOutputStream os = res.getOutputStream(); int bt = fis.read(); while (bt != -1) { os.write(bt); bt = fis.read(); } os.flush(); fis.close(); os.close(); } catch (final IOException ex) { Logger.getLogger(ApplicationController.class.getName()).log(Level.SEVERE, null, ex); } }
您的具体问题是您尝试通过Ajax下载文件。这是不正确的。JavaScript无法处理二进制响应,也没有任何强制执行“ 另存为” 对话框的功能。您需要改为使其成为普通的同步请求,以便由Web浏览器本身来处理它。
<h:commandLink value="Download" action="#{appController.downloadFile}" rendered="#{!file.directory}"> <f:param name="file" value="#{file.absoluteFilename}" /> </h:commandLink>
至于设置的内容类型,如果你有一个文件名以扩展在你的手中,你可以使用ServletContext#getMimeType()基于解决它<mime- mapping>的web.xml(无论是服务器的默认的一个或你的web应用的一个)。
ServletContext#getMimeType()
<mime- mapping>
web.xml
ServletContext servletContext = (ServletContext) externalContext.getContext(); String contentType = servletContext.getMimeType(file.getName()); if (contentType == null) { contentType = "application/octet-stream"; } response.setContentType(contentType); // ...
(请注意,我假设您正在使用JSF 1.x,看看如何获得servlet响应,因为JSF 2.x可以使用ExternalContext#getMimeType())
ExternalContext#getMimeType()