【问题标题】:JSF File upload in ui:repeatui中的JSF文件上传:重复
【发布时间】:2012-10-24 14:36:24
【问题描述】:

我有一个 UI,可以选择将多个特定性质的文档上传到一个问题。我可以在整个应用程序的其余部分上传单个文件而不会出现问题。

环境

  • Tomcat 7.0.x
  • Mojarra JSF 实施 2.1.3 (20110908-FCS)
  • JSF 2.1 和 Primefaces 2.2
  • 阿帕奇战斧。

代码说明

这是循环文档信息实体的代码。这些实体要么是来自数据库的记录,要么是占位符。如果实体存在,实体将有一个 ID 指向数据库中的项目,否则为 0,这意味着它是一个占位符并且可以上传文件。

在占位符的情况下,有一个上传按钮,它会弹出一个 Primefaces 对话框,其中包含一个 Tomahawk 文件上传组件。

代码

这是 JSF 代码:

<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core">

<ui:repeat var="extDoc" value="#{reportBean.externalDocs}"
        varStatus="extDocIdx">
    <!-- Display the document name -->
    <h:outputText value="#{extDoc.name}"/>

    <!-- if the document is not in the database, give the option to add it -->
    <ui:fragment rendered="#{extDoc.id == 0}">
        <!-- On click of the upload button, display the dialog -->
        <h:commandButton value="Upload" type="button"
            onclick="uploadDlg#{extDocIdx.index}.show()" modal="true"/>

        <p:dialog header='Upload document for #{extDoc.name}'
                modal="true" widgetVar="uploadDlg#{extDocIdx.index}"
                width="650" minWidth="650">
            Select the file to upload:
            <!-- THIS IS WHERE THE PROBLEM IS -->
            <t:inputFileUpload value="#{reportBean.uploadedFile}"/>
            <br/>
            <h:commandButton value="Submit"
                action="#{reportBean.addExtDocument(extDoc.name, extDocIdx.index)}"/>
        </p:dialog>
    </ui:fragment>

    <ui:fragment rendered="#{extDoc.id != 0}">
        <!-- display a link to the uploaded file -->
    </ui:fragment>
</ui:repeat>

以及ReportBean中的uploadedFile属性:

private UploadedFile uploadedFile;
public UploadedFile getUploadedFile() { return uploadedFile; }
public void setUploadedFile(UploadedFile value) { uploadedFile = value; }

public void addExtDocument(String name, int idx)
    throws IOException
{
    // access uploadedFile to persist the information
}

问题

我愚蠢地只有一个上传文件变量来处理上传文件的整个循环;因此,循环中的最后一项总是会覆盖其他项,因此除了最后一项之外,无法上传任何内容。我显然需要为每次循环指定不同的上传文件。我尝试使用 List 失败,但不清楚如何初始化数组或 t:inputFileUpload 组件如何更新提交时的值。

问题

所以问题是:我在 t:inputFileUpload 中包含什么类型的 EL,以及在 ReportBean 中使用什么类型的属性来在我的 addDocument 方法中提供单独的上传文件实例?

【问题讨论】:

    标签: jsf file-upload el uirepeat


    【解决方案1】:

    您可以使用List&lt;UploadedFile&gt;UploadedFile[] 并使用大括号表示法访问各个项目,其中您传递&lt;ui:repeat&gt; 的当前索引,如下所示:

    <t:inputFileUpload value="#{reportBean.uploadedFiles[extDocIdx.index]}"/>
    

    无论哪种方式,您都需要确保该属性已正确预初始化。 List 必须使用 new ArrayList&lt;&gt;() 进行初始化,并且数组必须使用正确的长度进行预初始化。 JSF/EL 即不会为您预先创建它;它只是在给定索引上设置给定项目,仅此而已。在null 列表或数组上,您只会面对PropertyNotWritableException,而在空数组或错误大小的数组上,您只会面对ArrayIndexOutOfBoundsException

    【讨论】:

    • 第一次尝试导致:javax.servlet.ServletException: IterationStatus{index=0, first=true, last=false, begin=null, end=null, step=null, even=true , current=null, iterationCount=0} 还在研究中。
    • 您应该将extDocIdx.index 传递给它,而不是extDocIdx。我宁愿将extDocIdx 重命名为更自我记录的loopiteration。它不代表索引,而只是循环/迭代状态,而循环/迭代状态又具有几个 getter getIndex()isFirst()isLast()getBegin() 等。
    • 就是这样,完全正确! 15 欧元通过 paypal 送达,以示感谢。
    • 我还按照您的建议将“extDocIdx”变量名更改为包含“loop”,而不是“Idx”。同意,这要明显得多。
    猜你喜欢
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    相关资源
    最近更新 更多