你好,我正在使用JSF和Primefaces进行文件上传和下载相同的文件操作。
我使用了来自不同论坛和博客的技术(BelusC的博客和Primefaces Showcase)。
下面是我的代码:这个操作的主要思想是让用户上传一个文件和为上传的文件生成一个下载链接,以便他可以下载并在提交前查看。
index.xhtml
<h:form>
<p:fileUpload showButtons="false" label="Attach Refrral"
auto="true" fileUploadListener="#{fileBean.uploadListener}"/>
</h:form>
<h:form >
<p:commandLink>
See Uploaded File
<p:fileDownload value="#{fileBean.refrralFile}"/>
</p:commandLink>
</h:form>
FileBean.java
private StreamedContent refrralFile;
public void uploadListener(FileUploadEvent evt)throws Exception
{
UploadedFile fx = evt.getFile();
File mainDir = new File("C:/","fileStorage");
if(!mainDir.exists())
{
mainDir.mkdir();
}
File subDir = new File(mainDir,"AttachedRefrrals");
if(!subDir.exists())
{
subDir.mkdir();
}
String fileName = fx.getFileName();
File f = new File(subDir,fileName);
FileOutputStream fos = new FileOutputStream(f);
IOUtils.copy(fx.getInputstream(), fos);
InputStream is = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getResourceAsStream(f.getAbsolutePath());
refrralFile = new DefaultStreamedContent(is, new MimetypesFileTypeMap().getContentType(f), fileName);
}
public StreamedContent getRefrralFile() {
return refrralFile;
}
使用上面的代码文件上传成功,但如果我点击文件下载链接,抛出异常:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
我使用了FacesContext# responseccomplete (),因为它被建议了很多地方,现在下载链接是不工作的。
请纠正我,如果我在我的技术或代码错误,并建议任何更好的方法,如果你知道。
默认情况下,<p:commandLink>
触发一个ajax请求。你不能通过ajax下载文件。负责处理ajax请求的JavaScript不知道如何处理检索到的二进制文件,因为它与预期的XML响应大不相同。出于明显的安全原因,JavaScript没有触发带有任意内容的Save As对话框的功能。
所以,要解决你的具体问题,使用
<p:commandLink ajax="false">
还是
<h:commandLink>
参见:
- 如何从JSF支持bean提供文件下载?
- PrimeFaces
<p:fileDownload>
展示页面-这也明确显示ajax="false"