JaclとサーブレットとJava Server Pages(JSP)

 Javaサーブレット(Servlet)は、JavaによるWebアプリケーションの基盤技術で、 Webブラウザからの要求に対して、共通ゲートウェイ・インターフェース(CGI) などと同じようにパラメータをGETまたはPOST経由で受け取り、 HTMLテキストを生成して送り返すWebサーバ上のプログラムのことです。
 また、サーブレットと共によく現れるJava Server Pages(JSP)は、 HTML文書の中にサーブレットの元になるJavaコードを部分的に埋め込んでおき、 サーバ側でそれらがサーブレットに「化ける」ことで、 HTML文書の部分をJavaコードの外の静的なテキストに分離したものです。
 JSPはサーブレットの応用技術で、 一般にサーブレットと同じ機能をより早く開発できます。 そのため、 実際の開発にはサーブレットよりもJSPが使われることのほうが多いようですが、 JSPの動作はサーブレットの動作を上からもう一層ラッピングしたものですから、 サーブレットを理解したうえでないとなかなか分かりにくいものです。 その意味で、両方のサンプルをご紹介することにしました。

●サーブレット/JSPを動かすには
 サーブレットやJSPを動かすには、 サーブレット/JSPコンテナと呼ばれるソフトウェアが必要です。 これはWebブラウザユーザーのリクエストに対してサーブレットを起動し (またはJSPを含むコンテンツからサーブレットを生成し)、 HTML出力を行わせて応答する機能をもつサーバーアプリケーションです。 WebサーバーのApacheへの拡張モジュールとして立ち上げるものもありますが、 一般にコンテナ自身がWebサーバの機能を兼ねます。 サーブレット/JSPコンテナの多くは、純粋Javaで書かれており、 OSに依存することなく導入することができます。 そのため、開発段階では無償配布のソフトウェアを使い、 運用環境では市販の製品にサーブレットを載せ換える、といったことも可能です。
 ここでサンプルの動作に使用したサーブレット/JSPコンテナは、 国産のBaykit XML Server(BXS)です。 これはオープンソースで開発されている無償のソフトウェアで、 サーブレット/JSPよりも、Web上でのXMLからのHTML文書の生成(XSLT変換) に主眼を置いているサーバーアプリケーションです。

●サーブレット/JSPを開発するには
 JSPを開発するには、テキストエディタ以外に特に必要なものはありません。
 サーブレットを開発するには、 サーブレットのクラスライブラリを入手する必要があります。 代表的なものは、Jakarta Project が開発しているサーブレット/JSPコンテナ、Jakarta Tomcatと共によく知られる 「Servlet API」があります。配布アーカイブを展開すると servlet.jar というJARファイルがあるので、これを環境変数CLASSPATHに通しておきます。

●Jaclサーブレットのサンプル
 サーブレットのアプリケーションディレクトリの配置ですが、 アプリケーションのディレクトリ名はとりあえず「sjacl」とでもします。 つまり、BXSの場合、

  • HTML文書、JSPを含むHTML文書は $BXS_HOME/webapps/sjacl に
  • サーブレット、JavaBeanなどのJavaクラスは $BXS_HOME/webapps/sjacl/WEB-INF/classes 以下に
  • JARファイルは $BXS_HOME/webapps/sjacl/WEB-INF/lib に
置くことになります。

import tcl.lang.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/**
 * Jaclの機能を使ってパラメータで指定された値の和を出力する
 * サーブレットです。
 */
public class ExprServlet extends HttpServlet {
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
        throws ServletException, IOException {

        String errorInfo = null, result = null;

        String valstr1 = request.getParameter("value1");
        String valstr2 = request.getParameter("value2");

        Interp interp = new Interp();
        try {
            interp.eval("expr " + valstr1 + "+" + valstr2);
            result = interp.getResult().toString();
        } catch(TclException e){
            errorInfo = e.toString();
        }

        PrintWriter out = response.getWriter();
        out.println("<html><body bgcolor=\"white\">");
        if(errorInfo != null){
            out.println("<h2>エラー</h2> パラメータの数値エラーです。<br>");
            out.println(errorInfo);
        }
        else{
            out.println("<h2>計算しました</h2> 結果:" + result);
        }
        out.println("</body></html>");
        interp.dispose();
    }
}
/* end. */


 これは、HTMLフォームから「value1」「value2」 という2つのパラメータを受け取り、Jaclのexprコマンドでそれらの和を計算し、 HTMLストリームに出力するサーブレットです。 サーブレットの基本的な書き方そのままにJaclのコードを埋めてみただけなんですが、 これはこれで、特に問題はないと思います。

 それでは、このサーブレットを呼ぶHTMLフォームの文書も一緒に作ってみましょう。 ファイル名は「exprsl-form.html」とします。

<html>
<body bgcolor="white">
<form action="/sjacl/servlet/expr" method="post">
数値を入力して下さい:
<input type="text" name="value1" size=14 maxlen=10>+
<input type="text" name="value2" size=14 maxlen=10> <br>
<input type="submit" value="検索">
<input type="reset"  value="クリア">
</form>
</body></html>

と、こんな感じです。サーブレットのパスを /sjacl/servlet/expr としましたが、「expr」が「ExprServlet.class」に当たる、 という対応付けは、「web.xml」と呼ばれるファイルでやります。 これはBXSの場合、demoディレクトリのweb.xmlをコピーして編集すれば簡単です。
(抜粋)
    <!-- Servlet config -->
    <servlet>
       <servlet-name>expr</servlet-name>
       <servlet-class>ExprServlet</servlet-class>
    </servlet>
それでは、もう一度、各ファイルの配置をまとめてみます。 簡単のために、「$BXS_HOME/webapps/sjacl」は「$SJ」と表記しています。
$SJ/WEB-INF/classes/ExprServlet.classサーブレット
$SJ/WEB-INF/lib/jacl.jarJaclのJARファイル
$SJ/WEB-INF/lib/tcljava.jarJaclのJARファイル
$SJ/WEB-INF/web.xmlサーブレットの情報を定義
$SJ/exprsl-form.htmlHTMLフォームを含むHTML文書

 これでexprsl-form.htmlにWebブラウザからアクセスしてみて、 動作の確認ができるはずです。

●Jacl-JSP文書のサンプル
 JSPの場合も、Jaclの扱いに別段注意は不要です。 JSPの基本にのっとり、書いていくだけで満足な出力が得られることでしょう。

<%@ page language="java" contentType="text/html;charset=EUC_JP" %>
<%@ page import="tcl.lang.*" %>
<html><head>
<meta http-equiv="Content-type" content="text/html;charset=EUC_JP"></meta>
</head><body bgcolor="white">
<%
Interp interp = new Interp();
String valstr1 = request.getParameter("value1");
String valstr2 = request.getParameter("value2");

if(valstr1.equals("") || valstr2.equals("")){
%>
  <h2>エラー</h2>
  パラメータに値を入力して下さい。
<%
}
else{
  try {
    interp.eval("expr " + valstr1 + "+" + valstr2);
    String result = interp.getResult().toString();
    out.println("<h2>計算しました</h2>");
    out.println("結果=" + result + "<br>");
    interp.dispose();
  } catch(Exception e){
%>
  <h2>エラー</h2>
  パラメータには数値を入力して下さい。<br>
  <%= e.toString() %>
<%
  }
}
%>
</body></html>


 今度もこのJSP文書のためのパラメータを入力するフォームページの HTML文書を作ります。

<html>
<body bgcolor="white">
<form action="expr.jsp" method="post">
数値を入力して下さい:
<input type="text" name="value1" size=14 maxlen=10>+
<input type="text" name="value2" size=14 maxlen=10> <br>
<input type="submit" value="検索">
<input type="reset"  value="クリア">
</form>
</body></html>

サーブレットのときのHTMLと、フォームのアクションURLが異なるだけで、 後は全く同じです。渡すパラメータが同じだから、当然ではありますね。

 それでは最後に各ファイルの配置のまとめです。 JSPを含むHTML文書は通常の静的なHTML文書と同じディレクトリに置けばよいので、 サーブレットよりも混乱は少ないはずです。 また、JSPの場合は、(BXSでは)web.xmlを書き換える必要はありません。
$SJ/expr.jspJSPを含むHTML文書
$SJ/WEB-INF/lib/jacl.jarJaclのJARファイル
$SJ/WEB-INF/lib/tcljava.jarJaclのJARファイル
$SJ/expr-form.htmlHTMLフォームを含むHTML文書

出力結果はサーブレットの場合とほとんど同じになるはずです。

拡張レビュー分室 top
(first uploaded 2001/10/18 last updated 2002/08/19, KENICHI USHIRODANI - KOUKEN HEIJIMA)