Wicket は
管理しています。
ログインを
誰でも
状態を
個人的に
認証な
Stateless に
Stateful に
前提 Wicket の Version
7.6.0です。
<dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket-core</artifactId> <version>7.6.0</version> </dependency>
参考記事
Wicket の コンポーネント に ついての 個人的な 理解
基本的に
大概の コンポーネントは ステートレス だが、 子の コンポーネントが ステートフル だと
ステートフル になる。 Link
と、Form
はステートフル なので、 Link
と、Form
を持つ コンポーネントは ステートフルに なる。 上記、
1. 、 2. に より、 何にも 考えないで 作っていると、 結構 ステートフル に なりやすい。
Link と Form を ステートレスに するには
Link には、
StatelessLink
、BookmarkablePageLink
を使うと、 ステートレスに なる。 1
[1] 当たり前かもですが、 ExternalLink の ステートレスです。 Form には、
StatelessForm
を用いると ステートレスに なる。 上記、
1.、 2.より Form
と、Link
をそれぞれ、 StatelessForm
、BookmarkablePageLink
に変えていくと、 結構 ステートレスに なりやすい。
ステートレスな ページか どうかを 確認するには
wicket/wicket-devutils at master · apache/wicket
のStatelessChecker
を
前に、
StatelessChecker
は
例外が
// add StatelessChecker getComponentPostOnBeforeRenderListeners().add(new StatelessChecker() { public void onBeforeRender(final Component component) { try { super.onBeforeRender(component); } catch (IllegalArgumentException | IllegalStateException e) { log.warn("Exception occurred..", e); } } });
ステートレスな 拡張コンポーネント
wicketstuff に
Wicket 8 では@deprecated
が
Wicket 7 に
以下、
pom.xml
には、
<!-- https://mvnrepository.com/artifact/org.wicketstuff/wicketstuff-stateless --> <dependency> <groupId>org.wicketstuff</groupId> <artifactId>wicketstuff-stateless</artifactId> <version>7.6.0</version> </dependency>
ステートフルな Page を、 ステートレスな ページに 書き換えていく
以下のような
Link
、Form
は、BookmarkablePageLink
、StatelessForm
に書き換える。 AjaxButton
は、StatelessAjaxButton
に書き換える StatelessChecker
をComponentPostOnBeforeRenderListener
として 追加。 動作確認して、
StatelessChecker
のログが 出力された 実装の 書き換えを 実施。
4.
で
AjaxPreventSubmitBehavior が ステートフル
AjaxPreventSubmitBehavior
が
以下の
StatelessAjaxSubmitBehavior
を
ですが、AjaxCallListener
が
相変わらず
AjaxCallListener
をAttributeModifier
を
private AttributeModifier getOnkeydownPreventSubmitAttributeModifer() { return AttributeModifier.replace("onkeydown", "if(event.keyCode==13 || window.event.keyCode==13){return false;} else {return true;}"); }
AjaxFormValidatingBehavior が ステートフル
AjaxFormValidatingBehavior
が、
java.lang.IllegalStateException: '[SynchTokenField [Component id = token]]' claims to be stateless but isn't. Stateful behaviors: org.apache.wicket.ajax.form.AjaxFormSubmitBehavior at org.apache.wicket.devutils.stateless.StatelessChecker.onBeforeRender(StatelessChecker.java:114) ~[festivals4partypeople-web-0.0.1.jar:0.0.1]
AjaxFormSubmitBehavior
とAjaxFormValidatingBehavior.FormValidateVisitor
のAjaxFormSubmitBehavior
を
原因のようです。
- コード抜粋
public void component(final FormComponent component, IVisit<Void> visit) { AjaxFormSubmitBehavior behavior = new AjaxFormSubmitBehavior(AjaxFormValidatingBehavior.this.form, AjaxFormValidatingBehavior.this.event) { //............略
AjaxFormSubmitBehavior
のStatelessAjaxFormSubmitBehavior
と
StatelessAjaxFormSubmitBehavior
にStatelessAjaxFormValidatingBehavior
を
StatelessAjaxFormSubmitBehavior
には、event
を
それがFeedbackPanel
が
MarkupId
のjavascript
エラーだったので、wicket:id
と
上手く
/** * Constructor * * @param id */ public ApplicationFeedbackPanel(String id) { super(id); setMarkupId(id); }
Transaction token 発行用に 作成した Hidden コンポーネントが 動かない。
上記の
Transaction token 発行に
2度押し
通常送信でも
[3] Form が
以下が
Wicket 6からCsrfPreventionRequestCycleListener
と
Origin
とReferer
に
Application クラスに
CsrfPreventionRequestCycleListener csrfPreventionListener = new CsrfPreventionRequestCycleListener() { @Override protected boolean isLocalOrigin(HttpServletRequest containerRequest, String originHeader) { return false; } }; csrfPreventionListener.addAcceptedOrigin("www.yourdomain.com"); getRequestCycleListeners().add(csrfPreventionListener);
これでReferer
が、www.yourdomain.com
の
説明1
isLocalOrigin()
でfalseを 返すのは、 testの ためです。 プロダクション環境で 使用する 場合は、 設定は 不要です。 説明2
csrfPreventionListener.addAcceptedOrigin("www.yourdomain.com");
でアクセスを 認める、 hostを 設定します。
まとめ
Stateful な
Form が
存在しない ページの Stateless化は 容易だが、 Form が 存在して、 且つ、 Ajax を 使用していると 途端に Stateless に するのが 難しくなる。 Stateful だと
Wicket 側の もともと 用意されている 部品群で いろいろできるが、 Sateless に すると 自前で 実装する 必要が 出てくる。 4
[4]stateless-parent
と使うと、 いい 感じでできるが、 それでも 多少不便 SEO 対策が
必要な ページは Stateless だが、 それ以外の ページは、 実装が 簡単なので Stateful に して おきたい。 思わぬ
ところに、 Stateful な コンポーネント、 ビヘイビアが いる。 StatelessChecker は 使った ほうが、 作業が 早く 進む。 CsrfPreventionRequestCycleListener のだけでなく、
同期tokenを 用いた チェックも したい。
まだ実装しきったとは
以上です。
コメント