0

フォーム全体を送信する前に画像を ajax アップロードしてプレビューする機能を備えたフォームで Primefaces を使用してページを作成しています。

これを達成するために、メインフォームの外側にダイアログを作成しました:

<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) によってサポートされていますが、値 Bean に渡すStreamedContentp:graphicImageは、セッション スコープまたはアプリケーション スコープである必要があります (メソッドが複数回呼び出されるため)。ImageBeanそこで、この目的のためだけに2 つ目のアプリケーション スコープ Bean ( ) を作成しました。

<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()内部imageBean.imageStreamedContent()は null を返します。

より正確 — setter が呼び出されなかったか、Bean の別のインスタンスで呼び出されたかのように、古い値を返します。String別のフィールドでチェックしました。ImageBeanコンストラクターで初期化し、ハンドラーで別の値でセッターを呼び出し、メインフォームの一部を更新しました。同じこと: コンストラクターからの古い値。

Bean のライフサイクルまたはスコープ固有の何かが欠けていると思います。それとも、このタスクを実装するためのより簡単な方法がありますか?

4

1 に答える 1