パスワードを忘れた? アカウント作成
432113 journal

quabbinの日記: JSPをオフラインで実行する(1)

日記 by quabbin

あけましておめでとうございます。
今年も一年、よろしくお願いいたします。

…という新年の定型文章はここまでにいたしまして…。

バッチとして日ごとや週ごとに変わるHTMLのページを作成するとき、皆さんはどうしてますか?
多くの場合、そういう普通のプログラムを組み、ファイル出力をしていると解答されるでしょう。
とはいえ、そのようなプログラムは、大方文字のエスケープがなんだのどうだのと、ごちゃごちゃして見づらいものになりがちですし、メンテナンスも少し手間が必要になるものになっているでしょう。

それが故に、人によってはDOMでデータを持ってきて、XSLで変換するとおっしゃるかもしれません。
ですが、XSLは非常にハードルが高いようで、新人君などに「やれ」と言っても、しばらくは四苦八苦しますし、また携帯端末向けの絵文字などを考えると、頭が痛くなるばかりです。

さて、このあたりでいいとこ取りをする方法はないものか…などと考えていると、ふと、PHPやJSPなどが、ハードルが低くてごちゃごちゃしにくいものであると思いつきました。
これでしたら、携帯端末の絵文字やらなんやらも問題なく通ります。
現在私が担当しているプロジェクトは、Javaで統一しています。
ということは、当然JSPという選択肢になるわけですが、どうやってJSPを実行した結果のHTMLを取得するか、少し考えてしまいました。
HTMLはローカルにファイルとしておいて置きたいわけです。間違ってもオンラインには置きたくない。
wget・CURL・HttpClientなどを使い、直接HTTPをたたくのもいいのですが、どうせならバッチ系。offlineでの動作を考え、統一的に扱いたいと思うのです。
そこで、offlineでJSPを動作させる方法はないか、以下で見ていこうと思います。

以下、Jakarta-Tomcat 4.1.30のお話。

JSPが期待通りに動作するには、まずweb.xmlでservlet-mappingしておかねばならなりません。
デフォルトでは、マッピングされるように設定しないため、普段は意識しないのですが…。
ここでマッピングにより呼び出されるServletは、org.apache.jasper.servlet.JspServletになります。

リクエストされたURLの拡張子がjspと判断された場合、マッピングによりJspServletが呼び出されます。
JspServletはまず、JSPの呼び出しURIを検索します。検索は
  1. HttpServletRequest#attributeの "org.apache.catalina.jsp_file"
  2. HttpServletRequest#attributeの "javax.servlet.include.servlet_path"
  3. HttpServletRequestのservletPath
の順に行われます。

次にGETパラメータにjsp_precompileの項目があるかどうかを探します。
  hoge.jsp?jsp_precompile&....
とか
  hoge.jsp?jsp_precompile=true&...
などといった場合、precompleオプションが選択されているものとして動作します(詳細は下段)。

次にリクエストされたURLの解釈を行います。
JSPのURL毎のインスタンスとして、org.apache.jasper.servlet.JspServletWrapperのインスタンスが生成される。WrapperはリクエストされたURLをキーとしてキャッシュされ、再利用されます。
JSPのURLを利用し、Wrapperはorg.apache.jasper.JspCompilationContextインスタンスを作成します。
JspCompilationContextは、JSPファイル→変換後のjavaソースコード→classファイルの、各ファイル格納絶対パス名を用意します。

wrapperはservice(HttpServletRequest, HttpServletResponse, boolean)を呼び出すことにより実行されます。

wrapperはまず、JspCompilationContextにJSPファイルのコンパイルをさせます。
JspCompilationContextはorg.apache.jasper.compiler.Compilerを利用し、JSPファイルをJavaソースファイルへ変換した後、classファイルにコンパイルします。
コンパイルが完了したら、そのクラスのインスタンスをClassLoaderで作成します。
この後、precomplile状態であれば、サービスを行わず、コンパイルのみで終了とあいなります。

JSPのインスタンスが作成されましたら、インスタンスをキャッシュします。
こうして、次に同一のJSPが呼び出されたときは、同一のインスタンスを提供するようにします。ただし、JSPファイルが更新された場合、インスタンスは破棄されます。
以上、完了したらservice(HttpServletRequest, HttpServletResponse)メソッドを呼び出し、HTMLの返却などをおこないます。

------------------------------------------------------------
基本的なJSPの呼び出しは以上で、結構簡単でした。
さて、ここからJSPのオフライン実行のさせ方を考えましょう。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

アレゲはアレゲ以上のなにものでもなさげ -- アレゲ研究家

読み込み中...