JSPとサーブレットの違いを明らかにする基礎から学ぶサーブレット/JSP(11)(2/2 ページ)

» 2004年03月18日 00時00分 公開
[山田祥寛@IT]
前のページへ 1|2       

文法からJSPとサーブレットの違いを見直す

 さて、サーブレットクラスの大枠の骨組みが明らかになったところで、より細部でJSPとサーブレットとが異なるポイントを、JSP特有の要素との対応関係という見地から見直してみることにしましょう。

ディレクティブや暗黙オブジェクトは使用できない

 サーブレットとJSPとの大きな違いは、JSP固有の要素(暗黙オブジェクトやディレクティブなど)が使用できないという点にあります。

 前述したように、暗黙オブジェクトrequestとresponseとはdoXxxメソッドの引数として宣言されていることから、事実上暗黙的に使用することができますが、そのほかの暗黙オブジェクトについては明示的に宣言する必要があります。以下に、サーブレットにおける主要な暗黙オブジェクトの生成方法について挙げておくことにしましょう。

主要な暗黙オブジェクトの生成方法
暗黙オブジェクト 生成方法
application ServletContext application=getServletConfig().getServletContext();
config ServletConfig config=getServletConfig()
out PrintWriter out=response.getWriter();
session HttpSession session=request.getSession();

 ディレクティブについても同様です。例えば、代表的な@pageディレクティブのcontentType属性については、サーブレットクラス内ではそのまま使用することはできないので、以下のように記述する必要があります。

response.setContentType("text/html;charset=Shift_JIS");

 setContentTypeメソッドは、PrintWriter(outオブジェクト)を生成する前にコールする必要がありますので、注意してください。outオブジェクトを生成した後にContent-Typeを設定しても、outオブジェクトの出力には反映されません。

サーブレットクラス内での「宣言部」

 JSPにおいて、変数・定数・ユーザー定義メソッドを宣言するに当たっては、<%!〜%>または<%〜%>に記述する必要がありました。それでは、サーブレットクラスで宣言部に当たるのはどの部分なのでしょうか。

 サーブレットクラスにおいて、いわゆる「宣言部」はdoXxxxメソッドと並列に記述する必要があります。具体的には、以下のようなイメージです。

package to.msn.wings.atmarkit;

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


public class SampleServlet extends HttpServlet {
  private int cnt=0;  // 変数の宣言
private static final String TITLE="WINGS";  // 定数の宣言
 private void LogRecord(String strMsg){
   // ユーザ定義メソッドの定義
 }

  public void doGet(HttpServletRequest request,HttpServletResponse response)
    throws ServletException,IOException {
    // ロジックの中身
  }
}

 ただし、「宣言部」で定義された変数はサーブレットクラスが初めてロードされてから、コンテナがアプリケーションそのものを終了するまで保持されるという性質がありました(詳細は第4回「JSPの基本構文を理解する」を参照してください。こうした性質を持つ変数を「インスタンス変数」といいます)。これは、サーブレットクラスにおいても同様です。もしもサーブレットクラスの呼び出しごとに変数を初期化したいという場合には、変数はインスタンス変数としてではなく、ローカル変数としてdoXxxメソッドの中で宣言する必要があります(インスタンス変数の利用に関する詳細は、「Java FAQ:複数のリクエストにはセッションオブジェクトを活用する」も併せて参照してください)。

サーブレットでは例外処理が必須

 Javaでは、原則としてアプリケーション中で発生する可能性があるすべての例外(RuntimeException=実行時例外を除く。検査例外ともいいます)に対して、例外処理を記述しなければなりません。例えば、Class.forNameメソッドはClassNotFoundException(クラスが見つからない)例外を発生させる可能性がありますが、これを明示的に処理するtry...catch...finally命令を必ず記述しなければならないということです。さもないと、「.java」ファイルのコンパイル時に「処理されない例外があります」などのエラーが発生することになるはずです。

 JSPではこうした例外処理を必ずしも意識する必要はありませんでした。というのも、これは別にJSPで例外処理が不要であるからではなく、JSPがサーブレットに変換される際に自動的に例外処理が補完されていたからなのです(もちろん、あくまで内部的なコンパイルを通すためだけの最低限の例外処理ですので、必要に応じて例外時の処理を記述すべきであるのはいうまでもありません)。

 しかし、サーブレットでは、こうした自動的な補足は行われません。そこで、必ず処理中に発生するすべての例外に対するtry...catch...finally命令を記述する必要があります。各メソッドが発生し得る例外情報については、サン・マイクロシステムズが公開する「Java2 Platform, Standard Edition, 1.4.0 API 仕様」のページを参照してください。

Java2 Platform Standard Edition 1.4.0 API 仕様のページ Java2 Platform, Standard Edition, 1.4.0 API 仕様のページ

 ちなみに、本稿サンプルで指定しているException例外はすべての例外のスーパークラスです。本来、個々のメソッドで発生し得る例外を個々にcatchブロックで処理していくのがより好ましい姿ですが、本稿ではコード簡略化のために割愛します。

 取りあえずコンパイルを成功させるだけならば、Exceptionクラスで例外を受け取っておき、catchブロック内はブランクにすることも可能ですが、これは例外の発生を隠ぺいしてしまうという意味でもあまりお勧めできません(例外が起こっても、エラーメッセージすら表示されなくなってしまいます)。意味ある例外処理がその場で可能であるならば、もちろんきちんと処理するのが好ましい姿ですが、もしもその場で処理できないならば、最低でも、本稿サンプルのように呼び出し元に例外を返すようにしてください。

 以上、サーブレットクラスの構文規則を、これまで学習してきたJSPとの比較という観点から見てきました。こうして見ていくと、確かにサーブレットにはいくつかの「JSPでは意識する必要がなかった」構文ルールこそありますが、いずれも極めて定型的な「決まりごと」の世界で、根本的なところで違う点はほとんどないということがお分かりいただけたのではないかと思います。

 もちろん、オブジェクト指向の概念として、より深く知っておいた方がよいところがあるのも確かですが、それはまず「決まりごと」を押さえ、取りあえずはサーブレットを実際に記述できるようになってからでも決して遅くはないでしょう。クラスやオブジェクトといった概念に惑わされて、入り口のところで二の足を踏んでしまうとしたら、実に本末転倒な話でもあります。

 まずは、前回までに登場した各JSPサンプルを実際にサーブレットクラスで書き換えてみて、サーブレットに慣れる練習をしてみるのもよいのではないでしょうか。

 さて、次回はサーバサイドJavaを構成するうえで、もう1つ重要な要素であるJavaBeansについて学習します。ビジネスロジックの再利用化を促進するJavaBeansクラス。その名前から一見特殊なクラスにも思われますが、サーブレットがそうであったように、いくつかの特徴的なルールをさえきちんと押さえてしまえば、なんら難しいところはありません。恐れず、一緒に手を動かしながら学んでいきましょう。どうぞお楽しみに。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。