我正在制作页面使用Primefaces的形式,具有ajax的能力-上传图像和预览之前,提交整个表单。
为了实现这一点,我在主表单之外创建了对话框:
<p:dialog id="imageDlg" header="Load Image" modal="true"
widgetVar="imageUploadWidget">
<h:form id="imageForm" enctype="multipart/form-data">
<p:fileUpload mode="advanced" auto="true" sizeLimit="9999999"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
fileUploadListener="#{pageBean.imageUploadHandler}">
</p:fileUpload>
</h:form>
</p:dialog>
在主表单中有p:graphicImage
组件显示,只是上传的图像和按钮显示对话框。页面由视图作用域bean (PageBean
)支持,但是要将StreamedContent
传递给p:graphicImage
值bean,则应该是会话或应用范围(因为方法称为乘次数)。所以我做了第二个应用程序作用域bean (ImageBean
)就是为了这个目的。
<p:graphicImage value="#{imageBean.imageStreamedContent()}"/>
<p:commandButton value="Choose image" type="button"
onclick="imageUploadWidget.show();"/>
ImageBean
码
@ApplicationScoped
@ManagedBean
public class ImagesBean implements Serializable {
private byte[] image;
//getter & setter
public StreamedContent imageStreamedContent() {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
return new DefaultStreamedContent(new ByteArrayInputStream(getImage()));
}
}
}
下一部分是fileUploadListener
。Idea是简单的--设置PageBean
的相应字段(以便在表单提交时保存它)、ImageBean
(在部分刷新后显示)和更新主表单的一部分:
@ManagedBean
@ViewScoped
public class PageBean implements Serializable {
@ManagedProperty(value="#{imageBean}")
ImagesBean imagesBean;
...
public void imageUploadHandler(FileUploadEvent event) {
getImagesBean().setImage(event.getFile().getContents());
RequestContext.getCurrentInstance().update("form:tabPanel1");
}
奇怪的东西来了。在setImage()
方法中,一切都是OK的--字段设置,getter工作得很好。但是,页面刷新之后,imageBean.getImage()
在imageBean.imageStreamedContent()
中返回null。
更准确地说,它返回旧值,就好像setter从未被调用或被调用在bean的另一个实例上一样。我在另一个String
字段上检查了它:在ImageBean
构造函数中初始化它,在使用另一个值调用的处理程序中初始化它,并刷新主窗体的一部分。同样的东西:构造函数中的旧值。
我认为,我遗漏了一些关于bean生命周期或范围的特定内容。或者也许有不那么复杂的方式来实现这个任务?
发布于 2013-09-18 09:04:58
使用StreamedContent在p:graphicImage
和p:media
的Primefaces中存在问题。
你可以在Primefaces论坛这里上看到Cagatay对这个话题的评论。
根据我的经验,当我遇到这 (或多或少)的问题时,BalusC和这的答案帮助了我。
我使用一个saperate而不是Managedbean将动态内容流到p:media
(在mycase中)。
这是我的代码供您参考(如果您需要的话):
PreviewFileServlet.java
@WebServlet("/PreviewFile")
public class PreviewFileServlet extends HttpServlet {
public PreviewFileServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
String path = request.getParameter("PREVIEW_FILE_PATH");
logger.info("Received pathe for Preview:"+path);
try{
if(null!=path){
java.io.File f = new java.io.File(path);
if(f.exists()){
FileInputStream fin = new FileInputStream(f);
byte b[] = new byte[(int)f.length()];
fin.read(b);
response.setContentLength(b.length);
response.setContentType(context.getMimeType(path));
response.getOutputStream().write(b);
response.getOutputStream().close();
logger.info("File sent successfully for Preview.");
}
else{
logger.warn("File sepecified by path:-"+path+"-:, NOT found");
}
}
}catch(Exception e){
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
光斑码
<p:media value="/PreviewFile?PREVIEW_FILE_PATH=#{fileManager.previewFilePath}" />
希望这能有所帮助。而关于StreamedContent这一话题,在堆栈溢出本身就存在着很多问题,一遍又一遍。
https://stackoverflow.com/questions/18860263
复制相似问题