Apache Wicketを使ってみる
0. 事の始まり
ある筋から「Apache Wicketを学習しといて」とのお達しがきたので自分向けメモ。
1. Apache Wicketとは
公式の記載をざっくり集約するとこんなところ。
- 2000年代半ばのJava Webアプリケーションフレームワーク戦争の、数少ない生き残りの一つ(2004年に世に出た)
- Apacheソフトウェア財団のもと、Apache 2.0 Licenseで公開されているOSS
- Ajax対応機能を内包
- 多言語対応(デフォルトで25言語を内包)
- ページやコンポーネントはJavaオブジェクトとして扱える
- 複数タブ/ウィンドウへの対応
- ページやコンポーネントのテストのサポート
- CDIやSpring、GuiceなどのDIをサポート
- JPA、Bean ValidationなどのJava EE 6サポート
- 最新安定版のWicket 8では、Java SE 8の言語仕様に対応するため、Java 8とServlet API 3.1が必須に
まぁ、最後のやつは、いまどきならよほどのことがない限りクリアできていると思うけど。
※そのよほどの(ry
2. セットアップ
プロジェクト自体はMavenで管理可能。
※言うまでもないが、Maven自体の扱いについては割愛。
MavenのコマンドラインはQuick Start Wizardで作成できる。
このページで生成されたコマンドラインをターミナルに投入すれば、Mavenが必要なものをそろえてくれるんだが、Windows使いで、PowerShellを使うときには注意が必要。
PS > mvn archetype:generate `
>> "-DarchetypeGroupId=org.apache.wicket" `
>> "-DarchetypeArtifactId=wicket-archetype-quickstart" `
>> "-DarchetypeVersion=8.5.0" `
>> "-DgroupId=com.mycompany" `
>> "-DartifactId=myproject" `
>> "-DarchetypeRepository=https://repository.apache.org/" `
>> "-DinteractiveMode=false"
といった具合にmvn
の -D オプションをダブルクォーテーションで囲わないと、「出力ディレクトリがわからない」とMavenに怒られる。
ハイフンで始まる部分がPowerShellのオプションと解釈されてしまうのが、どうも原因なようだ。なお、DOS窓なら問題なし。
Mavenがプロジェクトを生成したら、mvn clean install
で必要ライブラリをダウンロードする。このあたりは、ほかのMavenプロジェクトと同じ扱い。
あとはIDEにMavenプロジェクトとしてインポートすれば、開発体制はとりあえず整う。
必要があれば、愛用のIDEにプラグインを入れてやろう。
3. 開発サーバの起動
生成されたpom.xml
をみると、dependencyブロックにJetty 9が含まれているので、
PS > mvn jetty:run
で localhost:8080 でJettyが起動する。
4. ページの構成など
Strutsなんかに代表されるクラシックなJava Webアプリケーションと違い、ViewとなるHTMLと、処理を受け持つJavaクラス(≒バッキングビーン)が1対1対応していて、ともに同じJavaパッケージ階層に置く必要がある。
このあたり、どちらかといえばASP.NETに近いかも。ただし、CSSなどを駆使して描画する枠線などは、独自タグのあるASP.NETと違い、普通にCSSで定義する。以下、GitHubにあるexampleから引用。
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<head>
<title>Wicket Examples - sample panel</title>
</head>
<body>
Everything outside of the <wicket:border> tags will be ignored.
Might be handy as preview code.
<wicket:border>
<div style="border: 2px dotted #fc0; width: 400px; padding: 5px;">
before the border contents <br />
<wicket:body/>
<br />after the border contents <br />
</div>
</wicket:border>
</body>
</html>
JSPとは違い、HTMLにカスタムタグを埋め込む形式なので、普通にプレビューできるのはいいと思う。
サブミットの処理については、バッキングビーンにViewのformに対応するインナークラスを定義して処理するそうな。
以下、こちらもGitHubにある公式のexampleから引用。
public final class GuestBook extends WicketExamplePage {
/** A global list of all comments from all users across all sessions */
private static final List<Comment> commentList = new ArrayList<>();
/**
* Constructor that is invoked when page is invoked without a session.
*/
public GuestBook() {
// Add comment form
add(new CommentForm("commentForm"));
// Add commentListView of existing comments
add(new PropertyListView<>("comments", commentList) {
@Override
public void populateItem(final ListItem listItem) {
listItem.add(new Label("date"));
listItem.add(new MultiLineLabel("text"));
}
}).setVersioned(false);
}
/**
* A form that allows a user to add a comment.
*
* @author Jonathan Locke
*/
public final class CommentForm extends Form<ValueMap> {
/**
* Constructor
*
* @param id The name of this component
*/
public CommentForm(final String id) {
// Construct form with no validation listener
super(id, new CompoundPropertyModel<>(new ValueMap()));
// this is just to make the unit test happy
setMarkupId("commentForm");
// Add text entry widget
add(new TextArea<>("text").setType(String.class));
// Add simple automated spam prevention measure.
add(new TextField<>("comment").setType(String.class));
}
/**
* Show the resulting valid edit
*/
@Override
public final void onSubmit() {
ValueMap values = getModelObject();
// check if the honey pot is filled
final String _comment = (String) values.get("comment");
if (_comment != null && !_comment.isBlank()) {
error("Caught a spammer!!!");
return;
}
// Construct a copy of the edited comment
Comment comment = new Comment();
// Set date of comment to add
comment.setDate(new Date());
comment.setText((String)values.get("text"));
commentList.add(0, comment);
// Clear out the text component
values.put("text", "");
}
}
/**
* Clears the comments.
*/
public static void clear() {
commentList.clear();
}
}
5. Ajax対応について
サブミット処理の応用。処理を受け付けるクラスの中で、AjaxFallbackLinkで発動用のリンクと紐づけ、AjaxRequestTargetに処理結果を渡す。
このしくみだと、JavaScriptでイベントハンドラをゴリゴリ書かなくてもAjax対応できるのはいいかもしれない。
6. データアクセス
Wicket自体にはデータアクセス用のコンポーネントはないので、Spring Dataなんかと組み合わせる必要がある。
7. 雑感
今回やったところとしてはこんなところ。
- Viewがあるページには、普通にHTMLのプレビューがきくので、画面の作成はJSPを使うものより効率よくできそう
- Ajaxをつかった動きのあるページの作成は、比較的簡単に作れそう
認証とテストについては、また日を改めて挑むことにしよう。
« 続々:BSoDとの戦いに挑む | トップページ | 続:Apache Wicketを使ってみる -データアクセス編- »
コメント
« 続々:BSoDとの戦いに挑む | トップページ | 続:Apache Wicketを使ってみる -データアクセス編- »
初めまして。
様々なフレームワークを触っておくのはためになりますね。
投稿: 師子乃 | 2020年7月26日 (日) 18時51分