連載
» 2004年07月08日 00時00分 公開

基礎から学ぶサーブレット/JSP(13):JavaBeansをサーブレット/JSPから利用する (1/2)

[山田祥寛,@IT]

 前回「第12回 JavaBeansのルールを知る」では、JavaBeansクラスを利用した具体的なサンプルを動かしてみると同時に、JavaBeansクラス固有の構文規則について学びました。しかし、前回も述べたように、JavaBeansクラスとはあくまでそれ単体で動作するものではなく、JSP&サーブレットと連携して初めて意味があるものです。

 最終回は、前回のメール送信アプリケーションを例に、JavaBeansクラスをJSP&サーブレットから利用する方法、また、一連の処理の過程でJavaBeansがどのように引き継がれているのか(データ授受の考え方)について、ご紹介することにしましょう。

 なお、サンプルのコードについては、第12回を参照してください。

サーブレットからJavaBeansクラスを利用する

 「JavaBeansクラス」というと、いかにも特殊なクラスのようにも思われるかもしれません。しかし、(前回も述べたように)JavaBeansクラスとは「再利用性を高めるために、ある一定の構文規則にのっとって記述された」という以外には、まったく普通のクラスであるにすぎません。

 従って、サーブレットクラスからJavaBeansクラスを呼び出すに際しても、何ら一般的なクラスライブラリを利用する場合と変わるところはありません。前回ご紹介したサーブレットクラスServletMailに注目してみましょう。

SendMail objMail=new SendMail();
objMail.setSmtp("smtp.xxxxx.ne.jp");
objMail.setToAdd(request.getParameter("toAdd"));
objMail.setCcAdd(request.getParameter("ccAdd"));
objMail.setBccAdd(request.getParameter("bccAdd"));
objMail.setFromAdd(request.getParameter("fromAdd"));
objMail.setSubject(request.getParameter("subject"));
objMail.setBody(request.getParameter("body"));
try {
    objMail.transform();
  } catch (Exception e) {
    throw new ServletException(e);
}

 ごく一般的なインスタンス化の構文「クラス名 オブジェクト変数=new クラス名();」の形式はこれまでと何ら変わるところはありません。前回も紹介したように、JavaBeansクラスは「引数なしのコンストラクタ」を使ってインスタンス化できるのが特徴なのでした。インスタンス化した後は、アクセサメソッドを介して必要なパラメータを設定し、transformメソッドでメール送信を行うだけです。

 本サンプルでは、サーブレットクラスとJavaBeansクラスが「たまたま」同一のパッケージに配置されているため、パッケージを意識することなくアクセスすることができましたが、属するパッケージが異なる場合には、import命令で適宜対象のパッケージをインポートする必要があります。

One Point

JavaBeansクラスは、通常のクラスと「まったく同様の手順」で利用することが可能です。


サーブレットからJSPにJavaBeansクラスを引き継ぐ

 (本当にしつこいようですが)JavaBeansクラスは単なる一般のクラスと何ら変わるところはありません。ですから、doXxxxxメソッド内でインスタンス化されたJavaBeansクラスは、(当然)サーブレットクラスの処理が終了すると同時に破棄されますし、ほかのページで再びインスタンス化したとしても、そこにセットされたプロパティ値はすべて初期値となってしまいます。

 つまり、本稿の例のように、サーブレットクラスでセットしたJavaBeansクラスのプロパティ値に、ほかのファイル(ここではresult.jsp)からアクセスしたいと思った場合、JavaBeansクラスそのものを何らかの形で保持する必要があります。

 ここで登場するのが「リクエスト属性」なのです。リクエスト属性は、その名のとおり、「一連のリクエスト処理」の中でデータを保持します。「一連のリクエスト処理」とは、クライアントがサーバに最初の要求を出してから、最終的にサーバが応答を返すまでをいいます。例えば、本稿のサンプルではmail.htmlからデータがPOSTされてから、サーブレットクラスServletMail、JavaBeansクラスSendMail、result.jspと処理を遷移しているわけですが、これはあくまで「一連のリクエスト処理」と見なされます。

 リクエスト属性に値をセットするには、以下のように記述します。

request.setAttribute("SendMail",objMail);

 これによって、リクエスト属性"SendMail"にSendMailオブジェクトobjMailが格納されたことになります。

 なお、複数ファイル間で連携したリクエスト処理を実現する場合には、1点だけ注意すべき重要なポイントがあります。というのも、処理を遷移する際に、必ずforwardメソッドを使用しなければならないということです。本稿のサンプルでいえば、以下の部分がそれです。

getServletContext().getRequestDispatcher("/result.jsp")
.forward(request,response);

 見かけ上、forwardメソッドとよく似たメソッドとして、HttpServletResponse#sendRedirectメソッドがあります。例えば、

response.sendRedirect("/result.jsp");

のように記述することで、見かけ上はほぼforwardメソッドと同様の、「ページ間の移動」を実現することが可能です。しかし、リクエスト属性をページ(ファイル)間で引き継ぎたいという場合には、「必ずforwardメソッド」を使用しなければなりません。sendRedirectメソッドでページ間を移動した場合には、リクエスト属性は「引き継がれません」。

 この理由は、内部的な処理の違いを知っていれば自明でしょう。以下の図に、forwardメソッドとsendRedirectメソッドとの違いを示してみます。

図1 forwardメソッドとsendRedirectメソッドとの違い 図1 forwardメソッドとsendRedirectメソッドとの違い

 sendRedirectメソッドにおいては、元のページXから「いったん応答をクライアントに対して返している」のがお分かりになるでしょう。自動的にブラウザがサーバにページYの要求を行っているため、ユーザーの目にはあたかもページX、Yがまとめて実行しているように見えますが、sendRedirectメソッドにおいては、2つのページの処理はまったく別の(独立した)リクエスト処理であるといえます。先ほど申し上げたように、リクエスト属性は「一連のリクエスト処理」の中でのみ保持されますので、sendRedirectメソッドがいったんページXの処理を応答した時点で、リクエスト属性は破棄されてしまうのです。

 JSP&サーブレットの世界では、sendRedirectメソッドによるページ間の移動を「リダイレクト」、forwardメソッドによるそれを「フォワード」と呼び、それぞれを明確に区別しています。

One Point

JavaBeansクラスは「リクエスト属性」を介することで、複数のサーブレットクラス・JSPファイル間で共有することができます。ただし、サーブレット・JSP間の移動に際しては、必ずforwardメソッドを使用しなければなりません。


       1|2 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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