Cocoon2のJSPReaderとJSPGeneratorを使う |
Cocoonでは、正しいXML文書またはXHTML文書を出力するJSPスクリプトを、
Cocoonパイプラインに埋め込むことができます。
JSPReaderはJSPスクリプトからXHTML文書を生成するときに、
JSPGeneratorはJSPスクリプトからXML文書を生成するときに使います。
JSPを書く段階では、両者の違いは全くないと思います。
まず、sitemap.xmapの冒頭部に次のように
JSPGeneratorとJSPReaderを追加します。
<map:generators default="file">
<map:generator logger="sitemap.generator.jsp" name="jsp"
src="org.apache.cocoon.generation.JspGenerator"/>
</map:generators>
<map:readers default="resource">
<map:reader logger="sitemap.reader.jsp" name="jsp"
src="org.apache.cocoon.reading.JSPReader"/>
</map:readers>
|
ここで扱うサンプルは次のようなものです。まず、
下のようなタブ区切りのテキストファイル
「shiten.txt」があったものとして、これをJSPスクリプトで解析し、
XML文書にします。
その出力を受け取って、XSLスタイルシート shiten.xsl
で整形して、出力します。
shiten.txtです。
00100 東京 東京都港区北青山9-99-999 3 40
00120 さいたま さいたま市桜田99-99 3 200
00200 横浜 横浜市中区根岸町9-99-999 3 200
00250 川崎 川崎市中原区木月住吉町99-99 3 100
00300 大阪 大阪市北区茶屋町9-99-999 5 250
00400 札幌 札幌市清田区北野9条99丁目999 1 200
00500 名古屋 名古屋市中区栄9-99-999 4 250
00600 仙台 仙台市青葉区中央9-99-999 2 100
00900 福岡 福岡市中央区天神9-99-999 8 200
|
これを読んでXML形式で出力するJSPスクリプト、「shiten.jsp」です。
<?xml version="1.0" encoding="UTF-8"?>
<!-- ↑UTF-8にする必要あり -->
<%@ page language="java" contentType="text/html;charset=Shift_JIS" %>
<%@ page import="java.io.*, java.util.*" %>
<%@ page pageEncoding="Shift_JIS" %>
<data>
<%
String fileName = "/usr/javadeploy/cocoon/cocoon-test/jsp/shiten.txt";
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(fileName), "SJIS") );
int rows = 0;
while(true){
String buf = reader.readLine();
if(buf == null || buf.trim().equals("")) break;
StringTokenizer tok = new StringTokenizer(buf, "\t");
%>
<shiten>
<shiten-code><%= tok.nextToken() %></shiten-code>
<shiten-name><%= tok.nextToken() + "です。" %></shiten-name>
<address><%= tok.nextToken() %></address>
</shiten>
<%
}
reader.close();
} catch(IOException ex){
out.println("エラー!ファイル読み取りエラーにより…");
}
%>
</data>
|
注意点ですが、JSPGeneratorはエンコーディングがUTF-8でしか、
XML文書を生成できないようです。
そこで、1行目のxml version= encoding=のところのエンコーディングは
「UTF-8」を指定します。
但し、
このJSPスクリプト自体はシフトJISや日本語EUCでも構いません。
また、JSPの
page pageEncoding擬似命令は必ず指定してください。
省略するとこれまた文字化けが発生してしまいます。
そして、XSLスタイルシート「shiten.xsl」です。
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="Shift_JIS" version="1.0"
doctype-public="-//W3C/DTD XHTML 1.0 Strict/EN"
doctype-system="DTD/xhtml1-strict.dtd" />
<xsl:template match="/data">
<html lang="ja">
<head><title>支店情報</title></head>
<body bgcolor="white">
<h2><font color="#700040">支店情報</font></h2>
<table border="1">
<tr bgcolor="#ffcccc">
<th>支店コード</th><th>支店名称</th><th>所在地</th>
</tr>
<xsl:for-each select="shiten">
<tr>
<td nowrap="1"><xsl:value-of select="shiten-code" /></td>
<td nowrap="1"><xsl:value-of select="shiten-name" /></td>
<td nowrap="1"><xsl:value-of select="address" /></td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
</xsl:stylesheet>
|
sitemap.xmapの書き方です。上記の例では、
shiten.jspは直接XHTMLを生成せず、XML文書を生成するので、
後者の書き方をすることになります。
<!-- JSPで直接XHTMLを生成する場合 -->
<map:match pattern="*.htm">
<map:read type="jsp" src="{1}.jsp" mime-type="text/html" />
</map:match>
<!-- JSPでXMLを生成し、XSLTでXHTMLを生成する場合 -->
<map:match pattern="*.html">
<map:generate type="jsp" src="{1}.jsp"/>
<map:transform src="{1}.xsl"/>
<map:serialize type="html"/>
</map:match>
|
ここでもうひとつ注意ですが(多いなあ!)、
JSPの解析にはサーブレットコンテナ、例えばJakarta TomcatのJSPエンジン
(Jasperと呼ばれています) を使います。
従って、要求するJSPスクリプトのパスは、
Cocoonから参照できるだけでなく、
同じパスでサーブレットコンテナからも参照できなければエラーになります。
Cocoonのサイトマップでmap:mountを使って隔離ディレクトリをマウントしている場合、
Cocoonからは見えてもサーブレットコンテナからは見えないパスというのができえますが、
それだとJSPはうまく動かないので注意が必要です。
私は結構はまりました。(-_-)
なお、JSPエンジンとしてJasper以外のものを使う場合には、
$APP_HOME/WEB-INF/cocoon.xconf の次の部分を変更します。
<jsp-engine logger="core.jsp-engine">
<parameter name="servlet-class" value="org.apache.jasper.servlet.JspServlet"/>
<parameter name="servlet-name" value="*.jsp"/>
</jsp-engine>
|
●デバッグが大変
JSP Readerなどを使ってJSPの開発を行った場合、JSPの構文エラーが起きた場合にも
org.apache.cocoon.ProcessingException: ServletException in JSPReader.generate()
というメッセージとスタックトレースしか表示されないため、
具体的にどのタグの構文がエラーなのかを知ることができません。
そこで、Cocoonとは別にサーブレット・コンテナに、
そのJSPを乗せて、初期表示が確認できる
(少なくとも構文エラーが起きていないことが確認できる)
環境を作るのがお勧めです。
また、もっととりやすい解決策は、
この例外を発生させるCocoonのソースファイルJSPReader.javaの例外処理部を改造して、
ログにスタックトレースを表示させる(e.printStackTrace())文を追加する手もあります。
私はこの方法を使っています。
●タグライブラリの使用
JSP環境はサーブレットコンテナの機能に依存します。
それで当然、JSTLやJakarta Taglibsなどのタグライブラリも使えます。
使いたいときには、普通のJSPアプリケーションの場合と同じく、
$COCOON_HOME/WEB-INF にタグライブラリデスクリプタを置き、
$COCOON_HOME/WEB-INF/lib にそのクラスライブラリを置き、
$COCOON_HOME/WEB-INF/web.xml にタグライブラリの参照を書き加えます。
(first uploaded 2003/02/02 last updated 2003/09/27, URANO398)
|