我创建了一个JSF应用程序,我想在页面中嵌入一个链接,当用户点击链接时,会触发后端bean进行一些XML序列化的操作,并弹出一个保存对话框,让用户选择保存文件的位置。我已经编写了JAXB代码。
这应该怎么做呢?
谢谢。
Content-Disposition
头设置为attachment
。这将弹出一个“另存为”对话框。您可以使用HttpServletResponse#setHeader()
来实现。您可以通过ExternalContext#getResponse()
获取JSF下的HTTP servlet响应。FacesContext#responseComplete()
以避免出现IllegalStateException
错误。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.
}
content-disposition: attachment
。response.getWriter().flush();
来强制让写入器将内容发送给客户端,然后再关闭写入器。在我的情况下,这会触发“另存为”弹出窗口。HttpServletResponseWrapper
实现时,才需要这样做。对于标准的Servlet和JSF实现,这绝对不是必需的。解决方案应该是修复包装器/写入器实现,而不是在代码中手动刷新writer。 - BalusC
h:commandLink
或h:commandButton
,但不要使用RichFaces、Ajax4jsf、IceFaces等ajax动力的UICommand
组件。 - BalusCh:commandButton
,现在当我点击按钮时,整个页面重新加载,没有出现保存对话框。该应用程序将不支持IE或Chrome(甚至无法测试)。现在不确定该去哪里查找问题。 - volvoxh:form
内?方法是否被实际调用?遵循这个列表来相互检查。 - BalusC