JavaScriptをHTMLに組み込んでサーバ上で(PHPのように)動かせたらとても良いと思う。そして一番手っ取り早くそれを実現するのはMayaaを使う事だと思う。以下その準備とサンプル。
注意: 手っ取り早くJavaScriptを使うという目的のサンプルなので、S2StrutsなどでMayaaを使う用途としてはあんまり一般的な使い方ではないかも。
準備: Java5とTomcatとMayaaをインストール
具体的な手順は以下参照。Mac OS Xの場合は最初から入っているjavaが使える(Java5なので。)
1-2. インストールしよう : Documentation - JavaServer Templates "Mayaa"
インストールと確認作業が終わるとwebappsの下にmayaaというディレクトリが出来ている。その下にJavaScript入りのHTMLファイルを置くとサーバ側で実行してくれるようになる。配置後は特に再起動等も不要。
例: sample.htmlを配置。
配置先: [TOMCATをインストールしたディレクトリ]/webapps/mayaa/sample.html
表示の為のURL: http://localhost:8080/mayaa/sample.html
サーバ側で動かすためにServletエンジンのTomcatやJavaのライブラリ(Rhinoなど)を使用しているけど、Javaでプログラムを書く必要は基本的に無い。
サンプル1. 動的な文字列を表示する
HTML上で「${」と「}」で囲った部分がJavaScriptとして評価され、その値が表示される。
以下は、現在のサーバ上での日時を表示するサンプル。
sample_date.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns:m="http://mayaa.seasar.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>日付表示サンプル</title> </head> <body> <h1>日付表示サンプル</h1> 現在の日付:${new Date().toLocaleString()} </body> </html>
出力結果:(http://localhost:8080/mayaa/sample_date.html)
日付表示サンプル 現在の日付:2007/12/16 15:29:37 JST
サンプル2. 繰り返し結果を表示する
繰り返し処理を行うサンプル。繰り返し処理にはforプロセッサを使用する。(リストの中身を繰り返し処理するforeachプロセッサもある。)
HTML中に<span m:inject="m:for" m:init="${ スクリプト1 }" m:test="${ スクリプト2 }" m:after="${ スクリプト3 }">〜</span>と記述すると、「${」と「}」で囲った部分がJavaScriptとして実行され、実行結果に従って〜の部分が繰り返し表示される。(スクリプト1: 開始時に実行、スクリプト2: ループ毎に最初に実行され、真ならループ継続、スクリプト3: ループ毎に最後に実行される。)
以下は、1~10までの二乗数を表示するサンプル。
sample_for.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns:m="http://mayaa.seasar.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>繰り返しサンプル</title> </head> <body> <h1>繰り返しサンプル</h1> <span m:inject="m:for" m:init="${ var i = 1; }" m:test="${ i <= 10 }" m:after="${ i += 1 }" > ${i}^2 = ${i*i}<br> </span> </body> </html>
出力結果:(http://localhost:8080/mayaa/sample_for.html)
繰り返しサンプル 1^2 = 1 2^2 = 4 3^2 = 9 4^2 = 16 5^2 = 25 6^2 = 36 7^2 = 49 8^2 = 64 9^2 = 81 10^2 = 100
m:forのm:initでvarで宣言した変数iを繰り返しの内部で使用している。スクリプト中の「&<>"'」などはエスケープする必要がある("i <= 10" → "i <= 10")
サンプル3. URLパラメータの値を取得する
リクエストの値を取得するには、定義済みオブジェクトparamを使用する。JavaScript内で「param.パラメータ名」と記述すれば、URLパラメータやformで渡した値を取得出来る。
条件によって表示を切り替えたい時は、ifプロセッサを使用する。HTML中に<span m:inject="m:if" m:test="${ スクリプト }">〜</span>と記述すると、「${」と「}」で囲った部分がJavaScriptとして評価され、条件が満たされる場合に<span>タグの内部が表示される。
以下は、名前を入力すると挨拶するサンプル。
sample_param.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns:m="http://mayaa.seasar.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>パラメータサンプル</title> </head> <body> <h1>パラメータ表示サンプル</h1> <span m:inject="m:if" m:test="${param.yourname != null}"> こんにちは、${param.yourname}さん </span> <span m:inject="m:if" m:test="${param.yourname == null}"> <form action="/mayaa/sample_param.html" method="POST"> 名前を入力してください: <input type="text" name="yourname"> </form> </span> </body> </html>
出力結果:(http://localhost:8080/mayaa/sample_param.html)
パラメータ表示サンプル 名前を入力してください: [ ]
テラゾーと入力
パラメータ表示サンプル こんにちは、テラゾーさん
GETだと文字化けする場合についての対処は後述
サンプル4. Javaのクラスを利用する
JavaScript内からJavaのクラスを利用出来る。Javaのクラスパッケージ名の前にPackages.を付けることでアクセスできるようになる。
以下は、RSSのfeed URLを指定するとサーバサイドで内容を取得して表示するサンプル
sample_java.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns:m="http://mayaa.seasar.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Java実行サンプル</title> </head> <body> <h1>Java実行サンプル</h1> <span m:inject="m:if" m:test="${param.url != null}"> ${ var dbfactory = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(); var builder = dbfactory.newDocumentBuilder(); var doc = builder.parse(param.url); var XPathAPI = Packages.com.sun.org.apache.xpath.internal.XPathAPI; var items = XPathAPI.selectNodeList(doc, '/RDF/item'); } ${items.getLength()}件取得<br> <table border="1"> <tr> <th>タイトル</th> <th>内容</th> </tr> <span m:inject="m:for" m:init="${ var i = 0, c = items.getLength(); }" m:test="${ i < c }" m:after="${ i += 1 }" > ${ var item = items.item(i); var titleNode = XPathAPI.selectSingleNode(item, 'title/text()'); var title = titleNode != null ? titleNode.getNodeValue() : ''; var linkNode = XPathAPI.selectSingleNode(item, 'link/text()'); var link = linkNode != null ? linkNode.getNodeValue() : ''; var descNode = XPathAPI.selectSingleNode(item, 'description/text()'); var desc = descNode != null ? descNode.getNodeValue() : ''; } <tr> <td><a href="${link}">${title}</a></td> <td>${desc}</td> </tr> </span> </table> </span> <span m:inject="m:if" m:test="${param.url == null}"> <form action="/mayaa/sample_java.html" method="POST"> URLを入力してください: <input type="text" name="url"> </form> </span> </body> </html>
出力結果:(http://localhost:8080/mayaa/sample_java.html)
Java実行サンプル URLを入力してください: [ ]
http://b.hatena.ne.jp/entrylist?mode=rss&sort=hot&threshold=2を入力
Java実行サンプル 30件取得 ........
GETで文字化けする場合のworkaround
GETだと文字化けするのはServletの仕様です。回避するにはTomcatの設定ファイルを変更する。conf/server.xmlのConnector定義にuseBodyEncodingForURI="true"を追加する。(cf: google:useBodyEncodingForURI)
テンプレートの置き場所を変えたい場合
webapps/mayaa/WEB-INFの下にclasses/META-INF/というディレクトリを作成し、以下の設定ファイルを配置
[TOMCATをインストールしたディレクトリ]/webapps/mayaa/WEB-INF/classes/META-INF/org.seasar.mayaa.source.PageSourceFactory
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE factory PUBLIC "-//The Seasar Foundation//DTD Mayaa Factory 1.0//EN" "http://mayaa.seasar.org/dtd/mayaa-factory_1_0.dtd"> <factory> <parameter name="absolutePath" value="/Users/terazzo/Labs/mayaa/html/"/> </factory>
上は所定のディレクトリの他に、"/Users/terazzo/Labs/mayaa/html/"の下も検索対象に含めるという例。複数記述する事も可能。
テンプレートの文字コードを変えたい場合
例:Shift_JISに変更
HTMLファイルのエンコードおよび内部のMETAタグのContent-Typeのcharsetを変える。
それだけだと入力値が化ける場合、webapps/mayaa/WEB-INFの下にclasses/META-INF/というディレクトリを作成し、以下の設定ファイルを配置
[TOMCATをインストールしたディレクトリ]/webapps/mayaa/WEB-INF/classes/META-INF/org.seasar.mayaa.provider.ServiceProvider
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE provider PUBLIC "-//The Seasar Foundation//DTD Mayaa Provider 1.0//EN" "http://mayaa.seasar.org/dtd/mayaa-provider_1_0.dtd"> <provider> <engine> <parameter name="requestCharacterEncoding" value="Shift_JIS"/> </engine> </provider>