Powered by SmartDoc

WebアプリケーションとJSPの基本

Webアプリケーションのしくみ

Webアプリケーション

Webアプリケーションとは、「ユーザがWebブラウザを使って何かを入力し、必要な結果を得る」Webページのことを言います。例えば、サーチエンジン、本の検索システム、商品の購入システム、掲示板などはWebアプリケーションに含まれます。

3層モデル

Webアプリケーションでは、図[3層モデル]のような「3層モデル(three-tier model)」というしくみがよく利用されます。これは、Webアプリケーションに必要な機能を3つに分けたものです。

3層モデル

左側の層はクライアントです。WebアプリケーションではWebブラウザを用います。ユーザは、WebブラウザからあるURLを呼び出すだけで、アプリケーションを利用できます。

中間の層では、Webサーバが動いています。Apacheが代表的ですね。また、Webサーバの中に、「Webコンテナ(あるいはサーブレットコンテナ)」と呼ばれるものが組み込まれており、後述するServletやJSPはこのWebコンテナ内で動いています。

右側の層はデータベースです。多くのWebアプリケーションでは、さまざまなデータを取り扱います。そのために、データベースを利用するのが良い場合が多くなります。

動的なページの作成

Webアプリケーションでは、ユーザからの入力があると、その入力に応じたページを「動的に」作成しなければいけません。

こうしたことを実現するために、CGI (Common Gateway Interface)などの技術があります。

例えばCGIでは、Webサーバ側でプログラムが動いています。ユーザからの入力に応じて、CGIプログラムが必要な処理を行い、結果を表示します。また「アクセスカウンタ」のように、ユーザからの入力がなくても、そのページが呼ばれると動作するCGIプログラムもあります。

CGIはとても便利です。ただ、次のような欠点もあります。

  1. プラットフォームごとにプログラムの互換性が問題となる。
  2. CGIプログラムが呼ばれるたびにプロセスを生成するので、処理が遅くなる。
  3. 「セッション管理」がやりにくい。セッション管理とは、ユーザとサーバの間でやり取りされる情報を記憶して管理することである。

Javaを使ったWebアプリケーションでは、Webブラウザからのリクエストを処理して動的なページを作成するため、ServletとJSPを使います。ServletとJSPを使うことで、先に示したようなCGIの問題点は解消されます。

Servletは、HttpServletというクラスを継承して、必要なメソッドをオーバーライドしたクラスです。CGIと同じように、プログラムからHTMLを出力できます。

JSPは、HTMLのソースにプログラムを埋め込んだものです。

ServletとJSPは、先に述べたように「Webコンテナ」と呼ばれるものの内部で動きます。Webコンテナを使うことで、ユーザからのアクセスが増えても、プロセスは1つしか走らないので、処理が重くならないという利点があります。Webコンテナは、Jakarta Projectの「Tomcat」が代表的です。

データベースの必要性

Webアプリケーションは、通常のアプリケーションと同じく、データを処理します。図書データを検索したり、商品の在庫リストを変更したり、新たな発注リストを作成したり、掲示板に書き込みされた記事を管理するなど、さまざまなデータをさまざまなスタイルで処理する必要があります。

こうしたデータは、多くの場合、保存されている必要があります。データを保存して活用するには、データベースを使うのが便利な場合がほとんどです。データベースを使うと、データベース管理システムが「同時アクセス」「トランザクション」「高速なアクセス」「データの整合性の維持」などを自動的に実行してくれるので、便利です。データベース管理システムと同じ処理を自分でプログラミングするのは、面倒な作業になります。

HTTPプロトコル

みなさんがあるWebページを見ようとするとき、Webブラウザを使ってそのページのURLを入力するか、あるいはリンクをクリックします。Webブラウザは、あなたが見たいページを置いているWebサーバに接続します。WebブラウザとWebサーバは、HTTPというプロトコルに従って通信します。

HTTP (HyperText Transfer Protocol)は、WebブラウザとWebサーバが通信するためのプロトコルです。HTTPの最新バージョンはHTTP/1.1であり、RFC 2616によって定められています。

Webブラウザからhttp://localhost:8080/examples/jsp/index.htmlというURLにアクセスするとき、WebブラウザとWebサーバは次のように働きます(図[HTTPプロトコル]参照)。

HTTPプロトコル
  1. Webブラウザは、URLを解析して、URL中のホストとポートに接続する。この場合、ホストlocalhostのポート8080番に接続する。
  2. WebブラウザとWebサーバとの接続が確立されると、Webブラウザは、Webサーバに対して要求(request)を出す。この場合、「/examples/jsp/index.htmlを取得する」という要求となる。
  3. Webサーバは、Webブラウザからの要求を処理して、応答(response)を返す。この場合、index.htmlの内容と、いくつかの関連する情報を応答とする。
  4. Webブラウザは、応答の内容を表示する。この場合、index.htmlの内容を表示する。

JSP のしくみ

JavaServer Pages (JSP)は、HTMLのソースに、特殊なタグとJavaプログラムを埋め込んだものです。

リスト[loop.jsp]がJSPのサンプルです。先頭に<%@と%>というタグがあります。また、<%と%>のタグに囲まれた部分と、<%=と%>に囲まれた部分にJavaのコードが埋め込まれています。

loop.jsp
<%@ page pageEncoding="Shift_JIS"
              contentType="text/html; charset=Shift_JIS" %>
<html>
<head>
<title>JSP: for 文を使ったサンプル</title>
</head>
<body>

<%
    for (int i = 1; i <= 5; i++) {
%>
        <p>サンプル<%= i %></p>
<%
    }
%>
</body>
</html>

<%と%>の間に、for文の一部が挟まれています。そして、for文のコードは途中で途切れ、HTMLタグが書かれています。もっとも、よく見ると<%= i %>のようにJavaプログラムの断片が埋め込まれています。その後に、<% } %>という部分があります。これは、先のfor文の始まりとなる中括弧"{"に対応した、閉じの中括弧"}"なのです。この例では、for文の条件に従って、

        <p>サンプル<%= i %></p>

の部分を繰り返し出力することになります。

<%= Javaの式%>の形は、式の取る値にtoString()メソッドを適用して得られる文字列に置き換わります。ここでの<%= i %>では、for文の変数iが1から5までの値になるので、それぞれ"1", "2", "3", "4", "5"という文字列に置き換わります。

このJSPページをloop.jspという名前で保存し、TomcatなどのWebコンテナに置いておきます。WebブラウザからこのJSPページにアクセスがあると、WebコンテナはJSPページに埋め込まれたコードを処理して、HTMLを生成します。この例では、次のようなHTMLが生成されます。

<html>
<head>
<title>JSP: for 文を使ったサンプル</title>
</head>
<body>

<p>サンプル1</p>

<p>サンプル2</p>

<p>サンプル3</p>

<p>サンプル4</p>

<p>サンプル5</p>

</body>
</html>

ブラウザでは、次のように表示されます。

出力例:

サンプル1
サンプル2
サンプル3
サンプル4
サンプル5

JSP の要素

JSPで使われる要素について説明しましょう。

ディレクティブ

JSPページ全体に関わることについて定義します。

構文:

   <%@ ディレクティブ名 属性とその値 %>

例:

<%@ page pageEncoding="Shift_JIS"
         contentType="text/html; charset=Shift_JIS" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.DateFormat" %>

この例の1行目で、JSPページそのもののエンコーディングを指定しています。この例では、Shift_JISにしています。2行目で、生成されるページがHTMLであり、文字コードがShift_JISであることを指定しています。さらに、3行目と4行目で、java.util.Dateとjava.text.DateFormatの2つのクラスをインポートしています。

宣言

変数を宣言します。

構文:

   <%! 宣言 %>

例:

   <%! int i = 0; %>
   <%! int a, b, c; %>
   <%! Circle c = new Circle(2.0); %>

最後のセミコロンを忘れないようにしましょう。

式を記述します。<%= Javaの式%>の形は、式が返す値にtoString()メソッドを適用して得られる文字列に置き換わります。セミコロンは付けません。

構文:

   <%= Javaの式 %>

例:

いまは
<br />
<%= df.format(d) %>
<br />です。

スクリプトレット

プログラムを記述します。

構文:

   <% プログラム %>

例:

   <%
     String name = null;
     if (request.getParameter("name") == null) {
   %>
   	     <p>not found!</p>
   <%
     } else {
         foo.setName(request.getParameter("name"));
     }
   %>

サンプルプログラム

現在の日時を表示する例です。

date.jsp
<%@ page pageEncoding="Shift_JIS"
         contentType="text/html; charset=Shift_JIS" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.DateFormat" %>
<html>
<head>
<title>JSP: 現在の日時を示すサンプル</title>
</head>
<body>

<%
    Date d = new Date();
    DateFormat df = DateFormat.getDateTimeInstance();
%>

<p>
いまは
<br />
<%= df.format(d) %>
<br />です。
</p>

</body>
</html> 

スクリプトレットの中でDateFormat型のdfというインスタンスを作っています。次の部分で、df.format()メソッドを実行することによって、現在の日時を表示しています。

<%= df.format(d) %>

HTMLのフォーム

サーチエンジンや掲示板のサイトでは、ユーザからの入力に応じてWebページが変化していきます。こうしたサイトでは、まずHTMLのフォームを使ってユーザからの入力を受け取ります。

フォームで姓名を入力してもらい、そのデータをそのまま出力する例を紹介しましょう。

最初に、このフォームのHTMLです。

doGet.html
<?xml version="1.0" encoding="Shift_JIS" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
      content="text/html; charset=Shift_JIS" />
<title>フォームのテスト</title>
</head>
<body>

<p>姓名を入力してください:</p>
<form method="get" action="name.jsp">
<p>姓: <input type="text" name="familyName" /></p>
<p>名: <input type="text" name="givenName" /></p>
<p>
<input type="submit" value="実行" />
<input type="reset" value="キャンセル" />
</p>
</form>

</body>
</html>

このフォームは、図[姓名を入力するフォーム]のような画面になります。

姓名を入力するフォーム

「姓」のところに入力された文字は、inputタグのname属性の値であるfamilyNameというパラメータに格納されます。同様に、「名」のところに入力された文字は、givenNameというパラメータに格納されます。

フォームから入力されたデータは、HTTPのPOSTメソッドかGETメソッドを使って、そのデータを処理するプログラムに渡されます。

JSPでの要求・応答の処理

request 変数と response 変数

JSPでは、Webブラウザからの要求を処理するためにrequestという変数を使います。また、Webサーバからの応答を処理するためにresponseという変数を使います。

まずはrequest変数の使い方を示しましょう。request変数のメソッドを利用することで、リクエスト行とヘッダの内容の一部を表示させています。

<%@ page contentType="text/html; charset=Shift_JIS" %>

<html>
<head>
<title>要求の処理</title>
</head>
<body>

<% request.setCharacterEncoding("Shift_JIS"); %>

<ul>
<li>Method: <%= request.getMethod() %> </li>
<li>Request URI: <%= request.getRequestURI() %> </li>
<li>Protocol: <%= request.getProtocol() %> </li>
<li>Remote Address: <%= request.getRemoteAddr() %> </li>
</ul>

</body>
</html>

getMethod()というメソッドでは、要求で利用したメソッド名を表示しています。

request.getMethod()

getRequestURI()は、リクエスト行で指定されたURIを返します。

request.getRequestURI()

getProtocol()は、リクエスト行で指定されたHTTPのバージョンを返します。

request.getProtocol()

getRemoteAddr()は、要求を送ったブラウザのIPアドレスを返します。

request.getRemoteAddr()

このJSPページの出力例を示します。

    * Method: GET
    * Request URI: /test/name.jsp
    * Protocol: HTTP/1.1
    * Remote Address: 127.0.0.1

もう一つの変数であるresponseは、主としてJSPページから他のページに処理をまかせるときに利用します。

クエリーの処理

JSPでは、GETの場合でもPOSTの場合でもrequest変数を使ってクエリー中のパラメータの値を取得できます。

<%@ page contentType="text/html; charset=Shift_JIS" %>

<html>
<head>
<title>入力された名前について</title>
</head>
<body>

<% request.setCharacterEncoding("Shift_JIS"); %>

<p>
姓:
<%= request.getParameter("familyName") %>
</p>

<p>
名:
<%= request.getParameter("givenName") %>
</p>

</body>
</html>

request.getParameter()というメソッドを使って、パラメータの値を出力しています。次の部分では、familyNameパラメータの値を出力しています。

request.getParameter("familyName")

Tomcat で JSP を動かす

Tomcat

JSPやServletを動かすには「Webコンテナ」が必要になります。

Tomcatは、Jakarta Project (http://jakarta.apache.org/)が開発しているWebコンテナです。Javaで書かれています。Jakarta Projectは、オープンソースのJavaプログラムをたくさん開発している団体です。そのため、Tomcatもオープンソースになっており、活発に開発が続けられています。

TomcatはApacheなどの既存のWebサーバに組み込んで使えるほか、Tomcat単独でもWebサーバとして使えます。

Tomcat のインストール

TomcatはJavaで動いているので、まずJ2SEがインストールされている必要があります。環境変数JAVA_HOMEがセットされているかどうかチェックしてください。もしセットされていなければ、J2SEがインストールされているフォルダを指定します。

次に、Tomcatをインストールします。

インストールが終わったら、CATALINA_HOMEという環境変数を設定します。この環境変数の値は、Tomcatをインストールしたフォルダの絶対パス名になります。

JSP を動かすためのファイル構成

ServletやJSPなどは、Webコンテナの内部で動きます。そのため、Tomcatの内部にServletやJSPを置く必要があります。

JSPページをTomcat上で動かすには、次のようにします。

まず、%CATALINA_HOME%/webappsフォルダの中に新たなフォルダを作成します。このフォルダの中にServletやJSPなどで構成されるWebアプリケーションが置かれます。ここでは、testという名前のフォルダを作成します。

JSPページは、testフォルダの中に配置します。

testフォルダ以下は、.warという拡張子を持つファイルにまとめることもできます。このファイルを「warファイル」と言います。warファイルは、jarファイルと同じフォーマットのファイルです。

testフォルダにloop.jspを追加したときのファイル構成は、次のようになります。

%CATALINA_HOME% -- webapps/ -- test/
                                 |
                                 |-- loop.jsp

WEB-INF フォルダと web.xml

さらに、testフォルダの中に、WEB-INFというフォルダを作ります。

WEB-INF/classesフォルダには、Webアプリケーションが直接利用するファイルが入ります。コンパイルしたServletのクラスファイルはこのフォルダに格納します。

WEB-INF/libフォルダには、Webアプリケーションが利用するライブラリが入ります。

WEB-INF/web.xmlファイルは、Webアプリケーションの設定を記述するDeployment Descriptor (DD)ファイルです。XMLで記述されています。Servletを使うときには、このファイルにServletの情報を記述する必要があります。JSPの場合は、情報を記述する必要はありませんが、このファイルそのものが無ければ動作しません。

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>JSP_Samples</display-name>
  <description>
     JSP Samples
  </description>
</web-app>

最終的なファイル構成は次のようになります。これで、JSPを動かす準備が整いました。

%CATALINA_HOME% -- webapps/ -- test/
                                 |
                                 |-- WEB-INF/ --- web.xml
                                 |             |- classes/
                                 |             |- lib/
                                 |-- loop.jsp

JSP へのアクセス

まず、Tomcatを起動します。

Tomcatがlocalhost上の8080番ポートで動いているとします。

loop.jspには次のURLでアクセスします。

  http://localhost:8080/test/loop.jsp

testフォルダ以下のファイル構成に変更があったり、修正を加えたりしたら、Tomcatの再起動が必要になります。