应用程序作用域bean的setter无法设置值

时间:2013-09-17 21:32:37

标签: jsf primefaces view-scope graphicimage

我正在使用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。想法很简单 - 设置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()

这是奇怪的事情。在imageBean.getImage()方法内部,一切正常 - 字段设置,getter工作正常。但随后页面刷新,imageBean.imageStreamedContent()内的String将返回null。

更准确 - 它返回旧值,就好像从未调用过setter或在另一个bean实例上调用了setter。我在另一个ImageBean字段上检查了它:在{{1}}构造函数中初始化它,在处理程序调用的setter中使用另一个值并刷新主窗体的一部分。同样的事情:来自构造函数的旧值。

我认为,我缺少关于bean生命周期或范围特定的东西。或者可能没有那么复杂的方法来实现这个任务?

1 个答案:

答案 0 :(得分:0)

在Primefaces中为p:graphicImagep:media使用StreamedContent时出现问题。
您可以在Primefaces论坛here中看到Cagatay Civici对此主题的评论。

根据我的经验,当我让BalusC的问题ThisThis得到更轻松(或多或少)时帮助了我。

我使用了一个saperate Servlet而不是Managedbean来将动态内容流式传输到p:media(在我的案例中)。

以下是我的代码供您参考(如果您需要):

<强> 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);
    }

}

Facelet代码

<p:media value="/PreviewFile?PREVIEW_FILE_PATH=#{fileManager.previewFilePath}" />

希望这会有所帮助。 在stackoverflow本身中有很多关于StreamedContent这个主题的问题,请经过一次。