3

特定の性質の複数のドキュメントを課題にアップロードするオプションを備えた UI があります。アプリケーションの残りの部分では問題なく 1 つのファイルをアップロードできます。

環境

  • トムキャット 7.0.x
  • Mojarra JSF 実装 2.1.3 (20110908-FCS)
  • JSF 2.1 と Primefaces 2.2
  • アパッチ・トマホーク。

コードの説明

ドキュメント情報エンティティをループするコードを次に示します。これらのエンティティは、データベースのレコードまたはプレースホルダーです。エンティティには、データベース内の項目が存在する場合はそれを指す ID があり、そうでない場合は 0 になります。これは、それがプレースホルダーであり、ファイルをアップロードできることを意味します。

プレースホルダーの状況では、Tomahawk ファイル アップロード コンポーネントを含む Primefaces ダイアログを表示するアップロード ボタンがあります。

コード

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 の UploadFile プロパティ:

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
}

問題

愚かなことに、アップロードされたファイルのループ全体を処理するために、uploadedFile 変数が 1 つしかありません。したがって、ループ内の最後のアイテムは常に他のアイテムを上書きし、最後のアイテム以外はアップロードできなくなります。明らかに、ループのたびに異なる UploadFile を指定する必要があります。List<UploadedFile> を使用しようとして失敗しましたが、配列を初期化する方法や、送信時に t:inputFileUpload コンポーネントが値を更新する方法が明確ではありません。

質問

問題は、t:inputFileUpload にどのような EL を含めるか、ReportBean のどのようなプロパティを使用して、addDocument メソッドで UploadFile の個別のインスタンスを使用できるようにするかです。

4

1 に答える 1

5

または のいずれList<UploadedFile>かを使用して、次UploadedFile[]のように現在のインデックスを渡すブレース表記を使用して個々のアイテムにアクセスできます。<ui:repeat>

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

いずれにせよ、プロパティが適切に事前に初期化されていることを確認する必要があります。Listで初期化する必要がnew ArrayList<>()あり、配列は正確に正しい長さで事前に初期化する必要があります。つまり、JSF/EL はそれを事前に作成しません。指定されたアイテムを指定されたインデックスに設定するだけで、それだけです。nullリストまたは配列では、のみに直面しPropertyNotWritableException、空の配列または間違ったサイズの配列では、のみに直面しArrayIndexOutOfBoundsExceptionます。

于 2012-10-24T14:39:10.493 に答える