わかりやすいJavaEEウェブ システム入門のCDIの章を読んでたのですが…
- 別にロガーを
@Inject
してもおもろくない FileUtil
を@Inject
してもおもろくない
という理由で、自作クラスを@Inject
して遊んでたけど、JSF力なさすぎて一日潰したので、そのまとめ。
Abstract
最初の画面
これの選手番号のリンクを押したら
この画面になる
新規登録を押したら
この画面になる
で、編集完了したら元の画面に戻る感じ
(上記は新規登録の場合のイメージ)
ようにしたい
環境
成功したやり方
画面とバッキングビーン
- 最初の画面 →
@SessionScoped
なbacking bean(@ManagedBean(name="index")
) - 編集の画面 →
@RequestedScoped
なbacking bean(@Named("edit")
)
@Inject
を使ってるとこ
index
とedit
の双方にPlayerRepository
という単なるList<Player>
(実装はCopyOnWriteArrayList<>
)をラップしただけのシングルトンオブジェクト(@Singleton
つけてる)を突っ込んでるedit
の方は@ManagedProperty("#{index}")
で最初の画面のbacking beanを受け取ってる
アクション
- 最初の画面で選手番号のリンクをクリックした場合→
#{index.edit(p.id)}
を呼び出して(p
はPlayer
ってオブジェクト)、編集の画面に移る - 最初の画面で新規登録のボタンを押した場合→
#{index.create()}
を呼び出して、編集の画面に移る - 編集の画面で姓名と名前と学年からフォーカスが外れた時にajaxでvalidationかます
- 編集の画面でキャンセルを押した場合→
#{edit.cancel()}
を呼び出して何もせずに最初の画面に戻る - 編集の画面で登録ボタンを押した場合→
#{edit.register()}
を呼び出して、PlayerRepository
のList<Player>
に追加あるいは、List<Player>
のオブジェクトを更新してから最初の画面に戻る
状態の受け渡し方
新規登録なのか、それとも既存選手の編集なのかを編集画面に渡したいので、index
の方に一度状態を持たせてから、edit
に移動させてる
index
の方のバッキングビーン(IndexBean
)
@Inject private PlayerRepository repo; private boolean newPlayer; private Long current; public String edit(Long id) { this.newPlayer = false; this.current = id; return EDIT; } public String create() { this.newPlayer = true; return EDIT; }
edit
の方のバッキングビーン(EditBean
)
@Inject private PlayerRepository repo; @ManagedProperty("#{index}") private IndexBean index; private boolean newPlayer; private Long id; @PostConstruct public void init() { this.newPlayer = index.isNewPlayer(); if(!this.newPlayer) { this.id = index.getCurrent(); Player p = repo.findPlayerById(this.id); // 以下略 } }
うまくいった理由(適当に考察)
- backing beanの初期化は下に貼り付けたツイートのようになっているっぽいので、
@PostConstruct
の前の段階でedit
の方にはindex
とrepo
が設定されている @ViewScoped
だとajaxリクエストが発生する、登録ボタンを押すなどのタイミングでインスタンスが生成されないので、newPlayer
が書き換えられることがない(@RequestScoped
にしていたら、タブ二つで片方は新規登録、片方は編集操作すると、新規登録の方でnewPlayer
が書き換えられていてヌルポで落ちた)
メモ : JSF
[at]RequestScopedだと[at]PostConstructはajaxとかが発生するたびに実行される
[at]ViewScopedだと[at]PostConstructはajaxで呼ばれても実行されない
— もちだでしたが、衰退しました (@mike_neck) 2015, 3月 28
@shinsan68k イマイチbacking beanの初期化の順番が???になってて、
インスタンス生成
↓
[at]Injectが付与されたフィールドに値設定
↓
[at]PostConstructのメソッド実行
っていう順番で合ってます?
— もちだでしたが、衰退しました (@mike_neck) 2015, 3月 28
考察その2
IndexBean
の方は@RequestScoped
でもよくね?(認証が必要なシステムのパターンを考慮していない)
結論
こっち見たほうが参考になる
あと、わかりやすいJavaEEウェブ システム入門の書評(別に頼まれたわけではない)
- なるほど、わかりやすい
- 著者のサイトからサンプルコード落とせるので、わからなくなったら見られるのもよい
- JavaEEに関する本はNetBeansが前提になっているので、他の有名IDEとか弱小IDEのことも忘れないであげてください。というか、IDE非依存に…(Oracleのチュートリアルを嫁という話だった(´・ω・`))
- Javaを書いている時間よりもxhtmlを書いている時間よりも、圧倒的にCSS書いている時間のほうが長くてつらい(grunt使うか、べつに画面の見栄えなんてどうでもいいという話だった(´・ω・`))
- xhtmlを書いている時間のほうがJavaを書いている時間よりも長くてつらい
おわり