p:文件内部p:对话框丢失@ViewScoped值

时间:2014-12-22 21:37:37

标签: jsf primefaces dialog view-scope

我正在尝试使用<p:fileUpload>更新多个文件。上传文件后,我设置了一个包含正常工作路径的List。

之后,用户必须填写其他一些可选信息,然后单击按钮(提交表单)。

当用户点击按钮时,public void handleFileUpload(FileUploadEvent event)上完成的所有关于列表的信息都将丢失。

我只需要在用户点击按钮时保存数据库中的路径,我不明白为什么值会丢失,我正在使用@javax.faces.view.ViewScoped

当正在处理handleFileUpload时,用户在屏幕上输入的内容尚不可用。

  • JSF 2.2
  • CDI
  • PrimeFaces 5.1

我将在下面的代码中省略一些部分,以避免使其变得庞大(如果您认为没有足够的信息告诉我)

XHTML:

<h:form>
    <!-- OMITED -->
    <p:dialog>
        <!-- OMITED -->
        <p:fileUpload fileUploadListener="#{csrBean.handleFileUpload}"
            mode="advanced"
            skinSimple="true"
            cancelLabel="Cancelar"
            multiple="true"
            auto="false"/>
        <!-- OMITED -->
    </p:dialog>
    <!-- OMITED -->
</h:form>

方法:

public void handleFileUpload(FileUploadEvent event) {
    UploadedFile file = event.getFile();
    String normalize = FilenameUtils.normalize("uploads/csr/"
            + csr.getNumero() + "/" + event.getFile().getFileName());
    File destino = new File(normalize);
    try {
        FileUtils.copyInputStreamToFile(file.getInputstream(), destino);
    } catch (IOException e) {
        e.printStackTrace();
    }

    CsrOsAnexo anexo = new CsrOsAnexo();
    anexo.setCaminho(normalize);
    anexo.setOs(csr.getRespostaRecente().getOs());      
    csr.getRespostaRecente().getOs().getAnexoList().add(anexo);


    FacesMessage message = new FacesMessage("Succesful", event.getFile()
            .getFileName() + " is uploaded.");
    FacesContext.getCurrentInstance().addMessage(null, message);
}

调试,我可以看到csr.getRespostaRecente().getOs().getAnexoList()填充了所有档案路径,但是一旦handleFileUpload()结束,我转到commandButton调用的方法,那些值就会消失,值也会消失。表格已填写。

1 个答案:

答案 0 :(得分:3)

模式对话框必须具有自己的表单。

<h:body>
    ...
    <p:dialog>
        <h:form>
            ...
        </h:form>
    </p:dialog>
</h:body>

因为,当模式对话框生成为HTML输出时,它被JavaScript重新定位到HTML <body>的末尾,导致它不再以任何形式存在。这种重定位对于保证与模式覆盖和z索引有问题的旧浏览器(读取:IE&lt; 9)的兼容性是必要的。生成的HTML DOM树最终看起来像这样(使用webbrowser的开发工具来查看它):

<body>
    ...
    <form>
        ...
    </form>
    ...
    <div class="ui-dialog ...">
        ...
    </div>
</body>

文件上传显然仍然没有表单,因为它自动创建一个隐藏的iframe,其中有一个表单来模拟“ajax体验”。但是,任何其他操作基本上都会丢失JSF视图状态,因此将重新创建任何视图范围的bean。