劣化Twitter作ってみた
習作がてら作ってみました。飽きたので放流します。 ソースはこちら。
http://www.nagaseyasuhito.net/nicola.zip
eclipseでWTP+m2eclipseで作りました。 pom.xmlもついてますが単体でビルドできるかどうかわかりません、ごめんなさい。 なのでwarもつけておきました。
一応こんな感じに動いています。
http://nicola.nagaseyasuhito.net/
使ったフレームワークは
wicket1.3.0-beta4
guice1.0
warp::persist
JPA(Hibernate3.2)
warp::persistはguiceでHibernate、JPAをイイ感じに使うためのやつです。 Dynamic FinderというKuina-DAOからCriteriaを抜いたようなのがありますが、wicket-guice環境だとちゃんと動きませんでした。
Kuina-DAOがSeasar非依存になるととても嬉しいなぁ。
Resource(主に画像)がSessionに入っちゃってるのでSessionがバカでかくなります。 SharedResourcesに入れたのはSessionに保存されないようにならないのかな、俺の書き方がいけないのかな。
LoadableDetachableModelの使い方が変です。 DataProviderのmodelメソッドでもっかいfindなりするのも面倒だしなぁ、setCacheableすれば気にならない、かな?
そんな感じで所々とても手抜きです。 DISり待ちでございます。
wicket-auth-rolesとonSubmitでpost dataを保持してくれない件
Wicket-1.3.0-beta3でますねー。 PasswordTextFieldのsetPersistenceがUnsupportedExceptionを吐くのでさっそくwicket-auth-rolesについてるSignInPageが使えなかったりしますが。 PaletteのRecorder問題も直ってよかった。
で、表題の件ですよ。
サインインが必要ないページ(PageA)でサインインが必要なページ(PageB)にForm#onSubmitすると、RestartResponseAtInterceptPageException吐いてサインイン画面に遷移しますよね。
で、ユーザー名パスワード入力してサインインするとFormで入力した値がnullになってPageBが呼ばれ(Form#onSubmitの場合)たり、PageAに戻ったり(FormにaddしたButton#onSubmitの場合)しちゃうんです。
週末この問題にハマってたんですが、一応解決策っぽいの。
formのmethodをgetにする。 イェイ、これだけ。
巨大なデータだったり、fileuploadがあったらどうなのかなぁとか思うんですが、getにしておけばこうすると問題なさげです。
というのもWicketさんはRestartResponseAtInterceptPageException吐いてサインインページに飛ばしたとき、戻り先(continueToOriginalDestination)はURLしか保持してないんですねー。 1年くらい前にMLにこの問題を言及した人が「んじゃyouがPOST DATA保持するの作っちゃいなyo!」みたいに書かれてたけど放置プレイでした。 そんなもんかー。
んじゃ、俺が作れって? うう、。
WebPageやhtmlを頻繁に書き換える場合
package net.nagaseyasuhito.sandbox; import org.apache.wicket.application.ReloadingClassLoader; import org.apache.wicket.protocol.http.ReloadingWicketServlet; public class SandboxWicketServlet extends ReloadingWicketServlet { private static final long serialVersionUID = 1L; static { ReloadingClassLoader.includePattern("net.nagaseyasuhito.sandbox.page.*"); } }
こんな感じにしとけばOKだと思います。 Filterも似たようなのがあります。
WTPはauto publishingをoffにしとくこと。
Wicket1.3のWicketTester
Wicket1.3になってWicketTesterはApplicationを継承しなくなったので、SeasarにS2WicketのSeasarComponentInjectionListenerの登録を任せる場合は、
<component name="wicketTester" class="org.apache.wicket.util.tester.WicketTester"> <initMethod> #self.getApplication().addComponentInstantiationListener(new org.seasar.wicket.injection.SeasarComponentInjectionListener(#self.getApplication())) </initMethod> </component>
こんな感じ。
Wicket1.3-beta-2とS2Wicket
なんとなくWicket1.3に手を出してみました。
apacheに移動してパッケージ名が変わったのでS2Wicketの方もちょっと手直し。
org.seasar.wicket.injection.InjectionProcessor
org.seasar.wicket.injection.S2ContainerHolder
org.seasar.wicket.injection.S2ContainerLocator
org.seasar.wicket.injection.SeasarComponentInjectionListener
のimport文を"wicket.*"から"org.apache.wicket.*"に変更で終わり。
わーい楽チン。
Wicketをfilterで動かす場合はS2Servletが使えないので、WebApplication#init()内で、
SingletonS2ContainerFactory.init();
すればとりあえず動くはず。
1.3で遊んでみるー。
WicketTesterのインジェクション
こんな感じ?
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components namespace="s2junit4"> <component name="context" class="org.seasar.framework.unit.impl.SimpleInternalTestContext" /> <component name="wicketTester" class="wicket.util.tester.WicketTester"> <initMethod name="addComponentInstantiationListener"> <arg> <component class="org.seasar.wicket.injection.SeasarComponentInjectionListener"> <arg>wicketTester</arg> </component> </arg> </initMethod> </component> </components>