WicketのサンプルをClickで動かしてみる

雑誌『Java WORLD』2006/09の記事『初めてのWicket』にあるサンプルプログラムをClickで書き直してみた。
最初は、Hello, world。プロジェクト名は、helloClickとし、EclipseでDynamic Web Projectをまず作成する。

hello.htm

単にメッセージを表示するだけのページからなる。Wicketでは、メッセージの表示にLabelというクラスをWebPageクラスのサブクラスにadd()しているので、ClickではFormになるのかと、一瞬思ったが、HTMLのコードを見てみるとFormを使う必要がないことがわかった。
Wicket版のHelloPage.htmlは以下の通り:

<?xml version="1.0" encoding="windows-31j" ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
	"http://www.w3.org/TR/xhtml/DTD/xhtml1-transitional.dtd>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:wicket="http://wicket.sourceforge.net/">
<head>
<meta http-equiv="Content-Type"
	content="text/html; charset=windows-31j">
<title>Hello Page</title>
</head>
<body>
<h1><span wicket:id="title"></span></h1>
<span wicket:id="message"></span>
</body>
</html>

これをClickで以下のようにした。(hello.htm)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type"
    content="text/html; charset=windows-31j">
  <title>$title</title>
</head>

<body>
  <h1><span class="title">$title</span></h1>
  <span class="message">$message</span>
</body>
</html>

WicketのHelloPage.htmlは、関連付くHelloPage.javaと同じディレクトリに置いたが、hello.htmは、関連付くHelloPage.javaとは同じディレクトリではなく、WebContentディレクトリ直下に置かれる。

HelloPage.java

hello.htmに関連付くHelloPage.javaは簡単で、hello.htm内の$title, $messageに対応する変数を持つだけ。

package com.fujitsu.fst.hal;

import net.sf.click.Page;

public class HelloPage extends Page {
    public String title = "Hello, Click";
    
    public String message = "こんにちはClick";
    
}

click.xmlとweb.xmlなどの作成

ページの構成は単純なので、あとはclick.xmlとweb.xmlを作れば一通りは動作する。
click.xml

<?xml version="1.0" encoding="UTF-8"?> 
<click-app> 

  <pages package="com.fujitsu.fst.hal" automapping="true"/>

  <headers>
    <header name="Pragma" value="no-cache"/>
    <header name="Cache-Control" 
            value="no-store, no-cache, must-revalidate, post-check=0, pre-check=0"/>
  </headers>
  
  <mode value="trace"/>

</click-app>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <servlet>
    <servlet-name>click-servlet</servlet-name>
    <servlet-class>net.sf.click.ClickServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>click-servlet</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>redirect.html</welcome-file>
  </welcome-file-list>

</web-app>

web.xmlの内容にあるとおり、http://localhost:8080/helloClick/をURLに指定すると自動的にhttp://localhost:8080/helloClick/hello.htmが実行されるようにredirect.htmlを用意する。
redirect.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><meta http-equiv="Refresh" content="0;URL=hello.htm"></head>
</html>

日本語表示の問題

実際にアプリケーションをデプロイして実行してみると、hello.htm内の$messageに対応する文字列が化けてしまう。「Click Java 日本語 表示」をキーワードにWebを検索してみると、『新・たけぞう瀕死の日記』(http://www3.vis.ne.jp/~asaki/p_diary/diary.cgi?Date=2005-12-12)にPageクラスのgetContentType()メソッドをオーバライドすることと、WEB-INF/velocity.propertiesを用意すればよい、とのことで(この場合、velocity.propertiesは不要だが)、これらを作成した。
HomePage.java

package com.fujitsu.fst.hal;

import net.sf.click.Page;

public class HelloPage extends Page {
    public String title = "Hello, Click";
    
    public String message = "こんにちはClick";
    
    public String getContentType() {
        return "text/html; charset=Windows-31J";
    }
}

WEB-INF/velocity.properties

input.encoding=Windows-31J
output.encoding=Windows-31J

ためしにhello.htmに日本語のテキストを入れ、デプロイしなおして、表示が正しくなされることを確認した。

Border Templateにする

Quick Start GuideでやっているようにBorder Templateにしてみる。

  • BorderPage.javaを用意する。パッケージが違うだけで、その他はGuideにあるものと同じ。
  • HelloPageクラスをBorderPageクラスのサブクラスになるようにHelloPage.javaを修正。
  • border-template.htmlを用意する。

border-template.htmlの内容は以下の通り:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>$title</title>
</head>

<body>
 
  #parse($path)
 
</body>
</html>

haiku表示アプリケーション

haiku表示アプリケーションをClickでやってみた。プロジェクト名は、haikuClickとし、EclipseでDynamic Web Projectをまず作成する。
Wicketでは、ビューとモデルが分離されるので、hello表示アプリケーションのほうが少しだけhaiku表示より手間がかかっていたが、Clickではほとんど変わらない。
BorderPageクラスは、hello表示で使ったものがそのまま使えるので、border templateを使うことにする。

haiku.htm

haikuを表示するビュー。タイトル文字列のあとに、HaikuPageクラスのpublicフィールドhaiku1st, haiku2nd, haiku3rdを並べるだけ。

<h1>Haiku</h1>
<p><span class="haiku1st">$haiku1st</span></p>
<p><span class="haiku2nd">$haiku2nd</span></p>
<p><span class="haiku3rd">$haiku3rd</span></p>

HaikuPage.java

あらかじめ用意しておいた5音、7音の句の配列からランダムに1句目、2句目、3句目になる文字列を選んで、publicフィールドhaiku1st, haiku2nd, haiku3rdに設定する。hello表示と同じように、getContentType()メソッドを用意しておく。

package com.fujitsu.fst.hal;

import java.util.Random;

public class HaikuPage extends BorderPage {
    private Random random = new Random();
    
    private String[] phrase5 = {
            "ありがとう", "終わってる", "意味不明",
            "愛してる", "締め切りは", "ゴスリング"
    };
    private String[] phrase7 = {
            "秋の夕暮れ", "春はあけぼの", "マイルスデイビス",
            "どんなときでも", "ミサイル発射"
    };
    
    private String getPhrase5() {
        return phrase5[random.nextInt(phrase5.length)];
    }
    
    private String getPhrase7() {
        return phrase7[random.nextInt(phrase7.length)];
    }
    
    public String haiku1st = getPhrase5();
    
    public String haiku2nd = getPhrase7();
    
    public String haiku3rd = getPhrase5();
    
    public String getContentType() {
        return "text/html; charset=Windows-31J";
    }
}

その他のファイル

WEB-INFに配置するclick.xml, web.xml, velocity.propertiesは、hello表示と同じ。border-template.htm, BorderPage.javaもhello表示と同じ。redirect.htmlは、content属性に指定する表示ページをhaiku.htmに変更。

次は

  • BMI表示アプリケーション(画面遷移なし/ありの2種類)
  • web.xmlservlet-mappingタグのテスト。*を使わずサーブレットを指定するにはどうするのか。