ICEfacesでアップロード その3

今週はNetBeansICEfaces強化週間なんだぜ?正確には7日からなので先週末からだけど。


とりあえず昨日の時点でファイルアップロード自体は何の問題もなくなった。だが、このままではあまりうれしくはない。


今日はファイルサイズがリミッターに引っかかった場合の処理と、アップロード中の状態表示の2本でお届けします。

ファイルサイズが大きすぎる場合

まず、ファイルサイズが大きすぎた場合何らかの処理をする必要がある。ファイルサイズが大きすぎたかの判定はアクションリスナーで行う。

public void inputFile1_processAction(ActionEvent ae) {
    InputFile inputFile = (InputFile) ae.getSource();
    if (inputFile.getStatus() == InputFile.SAVED) {
        text = String.format("%s:%d\n%s",inputFile.getFileInfo().getFileName(),
                inputFile.getFileInfo().getSize(),
                text);


    }else if(inputFile.getStatus() == InputFile.SIZE_LIMIT_EXCEEDED){
        text = "ファイルがでかすぎるってばよ\n"+text;
    }

}

とりあえずこれで保存が出来たか、ファイルサイズが大きいのでアップロードに失敗したかが判定できるようになった。「大きすぎる」という表示をすることは非常に大事だと思うのでこの処理は入れておきたい。

ファイルアップロードの状態表示

続いて、アップロードの状態の表示。ファイルサイズが大きい場合なにも画面が更新されないとユーザーは不安になる。アップロード中だよという表記は必要だろう。

幸いICEfacesはAAJAXバリバリ、Comet、リバースAJAXバリバリなおかげでこの辺は余裕で可能だ。

ファイルアップロードコンポーネントの「progressListener」を追加する。

コンポーネントを右クリックしたメニューで「イベントハンドラの編集」>「ProcessMyEvent」を選択するとメソッドの雛形もすべて創ってくれるのでこちらを使うと良い。メソッド名がダサいけど。

そして以下のように記述する。

public void inputFile1_processMyEvent(EventObject eventObject) {
   InputFile file = (InputFile) eventObject.getSource();

   int p = file.getFileInfo().getPercent();

   text = p+"%\n" + text;
}

getPercentというメソッドが用意されているためそれを使うだけでよい。


らくちんらくちん…と思うのはあまい。実はこのメソッドは確かに定期的に呼ばれているものの、ブラウザに画面が更新されるイベントが飛んでいないため、完了したときにのみ一気に表示されるのだ。これではなんのためのリバースAJAXか。


さて、ブラウザへ更新を通知する命令はなんだろうか。

ずばり「PersistentFacesState」だ!

これのインスタンスをstaticなgetInstanceで取得して、renderメソッドを呼ぶだけ。

ただし、注意しなくてはならないのがこのインスタンスを取得するメソッドはコンストラクタの中でよんでおくこと。非同期によばれるリスナーの中ではダメっぽいということ。


つまり以下のようになる。

PersistentFacesState state;
/**
 * <p>Construct a new Page bean instance.</p>
 */
public Page3() {
    state = PersistentFacesState.getInstance();
}

public void inputFile1_processMyEvent(EventObject eventObject) {
   InputFile file = (InputFile) eventObject.getSource();

   int p = file.getFileInfo().getPercent();

   text = p+"%\n" + text;
    try {
        state.render();//非同期に画面を更新する!
    } catch (RenderingException ex) {
        Logger.getLogger(Page3.class.getName()).log(Level.SEVERE, null, ex);
    }
}


実行!

パーセントの表記が次々表示されていく。ファイルのサイズが小さいとこうきれいに表示はされないので、テストするときにはサイズ制限のリミッターをあげて(web.xmlで設定する)50MB以上推奨。ファイルがどんなに小さくても必ず0%と100%の2回は呼ばれるようなので安心して欲しい。

やはりアップロードが進んでいるのが目に見えると安心する。画面が更新されていないと再読み込みやボタンを連打してサーバーに余計に負荷をかけるだけだからね。こういうところはしっかり作らないといけないと思う。