連載
» 2001年06月14日 00時00分 UPDATE

Tomcatを使う「JSPプログラミング」(3):JSPプログラミングの基本を覚える

[三谷純,タイムインターメディア]

前回はJSPを実行するための環境を構築し、サンプルプログラムを動作させるまでの説明をしました。3回目は、実際にJSPを用いたプログラミングの方法を見ていきます。JSPはJavaの文法にのっとったコーディングができますので、Javaプログラミングの経験をお持ちの方でしたら、スムーズに理解できることと思います。しかしながら、知っておかなければならないJSPに固有の記述方法も多数ありますので、今回はそれらに注意しながら見ていきましょう。


 さて、最初のプログラミングですので、まずは簡単なものから始めましょう。例として、ブラウザからの入力のないプログラムと、ブラウザからの入力を受け取るプログラムを紹介し、続いてメソッドを作成する方法を紹介します。

■ブラウザからの入力のないプログラム

 それではさっそくJSPのプログラムを見ていきましょう。次のコードは、刻一刻と変化する情報として一番簡単な「現在時刻」を表示するプログラムの例です。

<%@ page contentType="text/html; charset=euc-jp" %>
<%
// 内容: 時刻を表示する例
 
// 現在の時刻を取得
java.util.Date nowTime = new java.util.Date();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>時刻を出力する例</title></head>
<body>
<p>-- 時刻を出力する例 --</p>
<p>
現在の時刻は <strong><%= nowTime %></strong> です。
</p>
</body>
</html>

 実行結果は次のように、現在の時刻(サーバ側で処理された時刻)が表示されます。しばらく間を空けて再度アクセスすると、表示される時刻が変化するのを確認できるはずです。

出力結果 出力結果

1行目に、

<%@ page contentType="text/html; charset=euc-jp" %>

という記述があります。突然見慣れない記述が出てきましたが、これは日本語を使ってHTMLを出力する際の決まり事のようなものだと思っていただいて結構です。今回はJSPプログラムの出力をEUCコードで行うために、charset=euc-jpとしています。出力する文字コードに応じて、charset=Shift_JISのようにも指定します。

 この<%@ %>というタグはディレクティブと呼ばれ、ページを処理する方法についてさまざまな指定を行うために使用されます。今回は詳細を理解しなくても結構ですので、日本語を扱う場合は、このように最初に文字コードを指定するのだな、ということを覚えておきましょう。

この指定を行わないとcharsetとしてデフォルトのISO-8859-1が使用されます(この指定を行わなくてもブラウザ側の設定によっては文字化けせずに問題なく日本語が表示できます)。


 text/htmlの部分はMIMEタイプの指定です。場合に応じてtext/xmltext/plainなどを指定することがありますが、今回はHTMLの記述しか行わないので、text/html以外は指定していません。

 6行目では、java.util.Dateクラスの変数nowTimeを宣言し、インスタンスを生成しています。これは一般的なJavaの記述方法と同じですね。

 さて、14行目では、

<%= nowTime %>

という記述があります。これは、

<% out.print(nowTime); %>

と同義で、HTML文の中に文字列を出力するための記述方法です。どちらの記述でも同じ結果になりますが、わざわざout.print()を記述するのと比べると、<%= %>タグを使用した方が簡潔に記述できるので便利ですね。この<%= %>タグを使用する場合、式の後ろにセミコロンは必要ありません。

ところで、Javaの文法では変数を使用する前に必ず変数宣言を行う必要がありましたね。それでは、ここで突然出てくるoutは何でしょう?宣言せずに使ってよいのでしょうか?

これは、JSPがサーバ側でコンパイルされるときに自動的に生成される暗黙オブジェクト(Implicit Objects)の1つです(同じような暗黙オブジェクトはほかにも存在します)。このoutは、具体的には、javax.servlet.jsp.JspWriterというクラスのインスタンスです。ここではひとまず、「最初から準備されていて便利に使えるもの」と思っていただいて結構です。

余力があったら、Tomcatに付属するAPIドキュメントで、このJspWriterクラスのメソッドを調べてみましょう。print以外にもいくつかのメソッドがあることが確認できます。APIドキュメントは、$TOMCAT_HOME/ROOT/docs/api以下にあります。


 それでは次に、時刻によって表示するメッセージが変わるプログラムを作ってみましょう。さまざまなWebサイトで見かける「あいさつ」を表示するプログラム例です。時間帯は、早朝・朝・昼・夕方・夜・深夜に分けてみます。

<%@ page import="java.util.*"
contentType="text/html; charset=euc-jp" %>
<%
// 時刻に応じたあいさつを表示する例
 
// 現在の時刻を取得
GregorianCalendar calendar = new GregorianCalendar();
int nowHour = calendar.get(Calendar.HOUR_OF_DAY);
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>時刻に応じたあいさつを表示する例</title></head>
<body>
<p>-- 時刻に応じたあいさつを表示する例 --</p>
<p>
現在は <strong><%= nowHour %>時</strong> です。<br>
<strong>
<% if(nowHour >= 4 && nowHour < 7) { %>
まだ朝早いですね
<% } else if(nowHour >= 7 && nowHour < 12) { %>
おはようございます
<% } else if(nowHour >= 12 && nowHour < 15) { %>
お昼ですね
<% } else if(nowHour >= 15 && nowHour < 18) { %>
もう夕方になりました
<% } else if(nowHour >= 18 && nowHour < 22) { %>
夜になりましたね
<% } else if(nowHour >= 22 || nowHour < 4) { %>
深夜です
<% } %>
</strong>
</p>
</body>
</html>

 これを実行した結果は次のようになります。

出力結果 出力結果

 まず1〜2行目の、

<%@ page import="java.util.*"
contentType="text/html; charset=euc-jp" %>

という記述に注目しましょう。<% page ... %>タグ内のimport="java.util.*"という記述は、Java言語における、

import "java.util.*";

という記述と同義です。<% %>タグの中に直接<% import java.util.*; %>とは記述できないので注意してください。

 前回は、java.util.Dateという具合にクラス名を完全な形で記述していましたが、先頭でこのようにパッケージの使用を宣言しておくと、パッケージ内のクラス名を記述するだけでよいので楽ですね。

複数のパッケージをインポートする場合は、<%@ %>タグを複数回宣言しても結構ですし、カンマで続けて記述することもできます。また、contentTypeの記述は、同じタグの中に記しても、別に記しても構いません。キーワードの「page」を忘れないようにしましょう。

(例1)
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html; charset=euc-jp" %>
(例2)
<%@ page import="java.util.*, java.io.*" contentType="text/html; charset=euc-jp" %>

 さて、さらにプログラムを見ていきましょう。7〜8行目において、現在何時であるかを0〜23の間の整数値で取得しています。

 18〜30行目では条件分岐の処理を行い、出力するメッセージを切り替えています。

 一見奇妙に見えますが、if、for、whileなどのブロック文の中で、一度 %> タグでプログラミングの記述を終了し、テキストを記述した後、再度 <% タグでプログラミングの記述を再開しています。このようにすることで、ブロック文が処理されるタイミングでHTML文を出力することができます。

 例えば、次のコードでは“おはよう”というテキストが10個出力されます。

<% for(int i = 0; i < 10; i++) { %>
おはよう<br>
<% } %>

テキストの出力部分とロジック部分を、

<% ロジック %> 出力文 <% ロジックの続き %>

のように記述することで、処理に応じたテキストの出力が可能です。ただし、このようにブロック文中にテキストを入れてしまうと、

  • プログラミングの記述が、テキストの出力部分の記述に分断されてしまう
  • ロジックとHTML部分が混在し、メンテナンス性が低下する

というデメリットがありますので、一度String型の変数にテキストを格納することで、HTML部分には<%= %>タグによる出力ロジックしか含ませないようにする方法をお勧めします。もちろん、この使い分けは場合によりますが、今回のプログラムについてこの方法を実践したコードは次のようになります。処理と出力を分離できてすっきりしたように思いますが、いかがでしょうか?

<%@ page import="java.util.*"
contentType="text/html; charset=euc-jp" %>
<%
// 時刻に応じたあいさつを表示する例
 
// 現在の時刻を取得
GregorianCalendar calendar = new GregorianCalendar();
 
int nowHour = calendar.get(Calendar.HOUR_OF_DAY);
String message = "";
 
if(nowHour >= 4 && nowHour < 7) {
  message = "まだ朝早いですね";
lse if(nowHour >= 7 && nowHour < 12) {
  message = "おはようございます";
} else if(nowHour >= 12 && nowHour < 15) {
  message = "お昼ですね";
} else if(nowHour >= 15 && nowHour < 18) {
  message = "もう夕方になりました";
} else if(nowHour >= 18 && nowHour < 22) {
  message = "夜になりましたね";
} else if(nowHour >= 22 || nowHour < 4) {
  message = "深夜です";
}
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>時刻に応じたあいさつを表示する例</title></head>
<body>
<h1>時刻に応じたあいさつを表示する例</h1>
<p>
現在は<strong><%= nowHour %>時</strong> です。<br>
<strong><%= message %></strong>
</p>
</body>
</html>

 上記のプログラムの実行結果は前回と同じです。

■ブラウザからの入力を受け取るプログラム

 それでは、次の例としてユーザーに名前と生年月日をブラウザのフォームから入力してもらい、それを表示するプログラムを紹介します。通常は、入力した内容が想定しているものでない場合のエラー処理を先に行いますが、ここでは入力は常に正常と仮定します。

 入力を行うHTMLと、データを受け取って出力を行うJSPの2つのファイルによって構成されます。以下がそれぞれのファイルとその出力結果です。

●入力を行うHTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>入力ページ</title></head>
<body>
<p>-- 入力ページ --</p>
<p><form action="3-4.jsp">
お名前: <input type="text" name="name" size=32><br>
生年月日: <input type="text" name="birthday" size=20><br>
<br>
<input type="submit" value="OK">
</form></p>
</body>
</html>
出力結果 出力結果
●受け取った内容を出力するJSP
<%@ page contentType="text/html; charset=euc-jp" %>
<%
// ユーザーからの入力を出力する
 
// パラメータを取得
String name = request.getParameter("name");
String birthday = request.getParameter("birthday");
 
// 文字コードの変換を行う
name = new String(name.getBytes("8859_1"), "EUC_JP");
birthday = new String(birthday.getBytes("8859_1"), "EUC_JP");
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>ユーザーからの入力を出力する</title></head>
<body>
<p>-- ユーザーからの入力を出力する --</p>
<p><ul>
<li>お名前: <%= name %>
<li>生年月日: <%= birthday %>
</ul></p>
</body>
</html>
出力結果 出力結果

 それでは、プログラムコードを見ていきましょう。ブラウザから渡されたパラメータは、パラメータ名を引数とする次のメソッドで取得できます。このメソッドではPOSTとGETのどちらで渡されたパラメータでも取得できます。

request.getParameter(java.lang.String name)

 6〜7行目では、“name”と“birthday”という名前のパラメータを取得し、それを文字列namebirthdayに格納しています。

ここでのrequestも前回のout同様、変数宣言していないオブジェクトですね。requestも暗黙オブジェクトの1つなのです。

具体的には、javax.servlet.http.HttpServletRequestインターフェイスを実装したインスタンスです。outと同様、余力がありましたらAPIドキュメントでほかのメソッドも調べてみましょう。


 さて、このままではnameとbirthdayの文字列は、EUCコードで渡された日本語がそのままJavaの内部コードであるUnicodeとして扱われるため、出力の際に文字化けを起こしてしまいます。そこで、9〜11行目の、

// 文字コードの変換を行う
name = new String(name.getBytes("8859_1"), "EUC_JP");
birthday = new String(birthday.getBytes("8859_1"), "EUC_JP");

のコードによって、それぞれを正しい文字コードに変換しています。その後、19〜20行目で<%= %>タグを使用してこの文字列を出力しています。

■メソッドを作成する

 複雑な処理やライブラリとして使用する処理などは、JSPではなくサーブレットで実現することが多いので、JSPでメソッドを使用する機会はそれほど多くないかもしれません。それでも、当然のことながらJSPでもメソッドを作成できますので、同じような処理を行う必要がある場合などにはメソッドを作成すると便利です。

 次の例では、文字列に色を付けるメソッド、getColoredHTML(String str, String color)を作成してみました。具体的には、このメソッドは第一引数に指定された文字列(str)と、第2引数で指定された色(color)を用いて、

<font color="color">str</font>

という文字列を返します。

<%@ page contentType="text/html; charset=euc-jp" %>
<%
// メソッドを使用する例
 
String redText = getColoredHTML("赤いテキスト", "red");
String blueText = getColoredHTML("青いテキスト", "blue");
String greenText = getColoredHTML("緑のテキスト", "green");
%>
<%!
/**
 * フォントカラーの指定を行ったHTML文を作成する
 * @param str 色を付けて表示する文字列
 * @param color 色を指定する文字列
 * @return フォントカラーの指定を行ったHTML文
*/
public String getColoredHTML(String str, String color) {
return "<font color=\"" + color + "\">" + str + "</font>";
}
%>
<html>
<head><title>メソッドを使用する例</title>
<body>
<p>-- メソッドを使用する例 --</p>
<p>
<%= redText %><br>
<%= blueText %><br>
<%= greenText %><br>
</p>
</body>
</html>

これを実行させた結果は次のようになります。

出力結果 出力結果

 メソッドであるgetColoredHTMLの定義は16〜18行目で行っています。10〜15行目はJavaのコメント文ですので、これはなくても構いません。

 さて、9行目と19行目に、初めて見るタグ<%! %>が現れましたね。メソッドを宣言する場合は、このタグの中に記述します。複数のメソッドを宣言する場合は、1つの<%! %>タグに入れてしまってもよいですし、複数の<%! %>タグで分割して宣言することもできます。

 5〜7行目で、このメソッドを呼び出して<font color="color">str</font>という、色を指定するタグの付いたHTML文を生成しています。5行目を実行した結果として、変数redTextには、<font color="red">赤いテキスト</font>という文字列が入ります。

いままで見た中で、<%@ %>、<% %>、<%= %>、<%! %>という4つのタグが出てきましたね。<%@ %>タグはすでに説明したように、ページ処理の方法を指定するディレクティブと呼ばれる特殊なタグです。そのほかの3つのタグはスクリプティング要素と呼ばれ、それぞれ次のように使い分けます。

タグ 種類 説明
<% %> スクリプトレット 実際の処理の内容を指定のスクリプト言語(デフォルトでJava言語)で記述します
<%= %> 出力文を生成するのに使用します
<%! %> 宣言 この宣言文を含むJSPページに固有の変数とメソッドを定義するのに使用します

 さて、今回は簡単な例を紹介しながら、JSP特有のプログラミング方法について解説しました。今回の内容を理解することで、簡単なプログラムをご自身で作ることができるようになったのではないでしょうか?実際に手を動かして、JSPで遊んでみましょう。

著者プロフィール

三谷純

タイムインターメディア



Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

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

メールマガジン登録

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