目次へ戻る 下へ↓
31、J2EEにおけるWEBアプリケーション
作成者:Fumitaka Makino 更新日:2003-05-20 15:45

・WEBアプリケーション

サーバーサイドJavaにおけるWEBアプリケーションはServletAPI2.2を区切りに大きく変わりました。それはJ2EEのWEBアプリケーション形式への対応です。WEBアプリケーション形式はそれまで(つまりServletAPI2.1まで)ばらばらであったクラスファイルやHTMLのディレクトリ配置を規格化し、各サーブレットコンテナの互換性を向上させました。具体的に言うとコンテキストルート以下をディレクトリとし、そのディレクトリ以下をWEBアプリケーションとして扱うということです。またこのWEBアプリケーションディレクトリはJAR形式で圧縮された単一のWARファイル(WebARchive)として扱われます。下表にServletAPIとWEBアプリケーションの取り扱い、対応するTomcatのバージョンを示します。

表:ServletAPIのバージョン(2003/05時点)
ServletAPI
2.0
2.1
2.2
2.3

2.4
Final Draft

JSP
1.0
1.1
1.2
2.0
リファレンス
JSDK/JServe
Tomcat3.1
Tomcat3.2/3.3
Tomcat4.X
Tomcat5.X

J2EE

1.0?
1.1
1.2
1.3
1.4
WAR対応
×
×
BEA WebLogic
4.x?
5.X
6.X
7.X
-
IBM WebSphere
3.0?
3.5
4.X
5.X
-

ここで注意しなければならないのが、2.2以降はServletAPIのバージョンはAPIセット(通常servlet.jar)のバージョンだけではなく、WEBアプリケーションの配置情報を記述するweb.xml(正確にはそのDTD)のバージョンにも影響するということです。つまり、ServletAPI2.3対応のWEBアプリケーションはAPIセットが2.3であってさらにweb.xmlが2.3の文法で記述されている必要があるということです。

・ディレクトリ構成

いよいよWEBアプリケーションディレクトリの詳細を説明します。下図に標準的なWEBアプリケーションのディレクトリ構成を示します。

図:WEBアプリケーションの配置図

まずディレクトリはコンテキストルートから開始します。コンテキストルートの下は、WEB-INFディレクトリを除いて、通常のホームページのサービスと同様に、好きなようにディレクトリを作り画像やHTMLを配置することができます。またJSPも同様に配置することが可能です。WEB-INFディレクトリは必ず存在しなければならず、さらにWEB-INFディレクトリはクライアントからは隠蔽されブラウザではアクセスすることはできません。WEB-INFディレクトリはクラスやサーブレットの配置情報やJARファイルを保持する特別なディレクトリです。WEB-INF直下には、必ずweb.xmlファイル、libディレクトリ、classesディレクトリが存在します。web.xmlファイルはサーブレットなどの配置情報が記述されたXMLファイル、libディレクトリはJDBCやその他のAPIを利用するときのJARファイルを配置するディレクトリ、classesディレクトリはサーブレットやその他の関連クラスを配置しておくディレクトリです。さらにTomcatに関してはjspディレクトリを用意し、ディスパッチによる転送でのみWEB-INF/jsp以下のjspファイルに転送を許可しています。また慣習によりsrcディレクトリを用意し、コンパイル前のソースファイルをsrc以下に配置しておくこともあります。そしてこれらのコンテキストディレクトリ以下をJAR形式で圧縮して一つのファイルとしたものをWARファイルと呼びます。ちなみにJ2EEで用いるEAR(EnterpriseARchive)ファイルは、その配下にWARファイルEJBのJARファイルDD記述子(XMLファイル)を持つディレクトリの圧縮ファイルです。


・web.xmlの記述

基本的なweb.xmlの記述は以下のようになります。

例:ServletAPI2.3のweb.xml(赤字はコメントのため実際には記述されていません)

     
 

<?xml version="1.0" encoding="Shift_JIS"?>//XML自体の宣言

<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">//このweb.xmlで利用するDTDの宣言

<web-app>
  
  <display-name>シンプルなサンプル</display-name>
  <description>
   web.xmlの設定のシンプルなサンプル
  </description>
  
  <!-- サーブレットのクラス名による呼び出しフィルターの宣言 -->
  <filter>//フィルタの宣言
    <filter-name>Servlet Mapped Filter</filter-name>//内部での宣言名を記述
    <filter-class>filters.ExampleFilter</filter-class>//上記フィルタ宣言名で利用するクラス名
  <init-param>//フィルタ内で利用する初期値
    <param-name>attribute</param-name>//初期値の名称
    <param-value>filters.ExampleFilter.SERVLET_MAPPED</param-value>//初期値の値
  </init-param>
  </filter>
  
  <filter>
    <filter-name>Path Mapped Filter</filter-name>
    <filter-class>filters.ExampleFilter</filter-class>
  <init-param>
    <param-name>attribute</param-name>
    <param-value>filters.ExampleFilter.PATH_MAPPED</param-value>
  </init-param>
  </filter>
  
  <!-- ServletRequestにキャラクタエンコーディングをセットするフィルタの宣言 -->
  <filter>
    <filter-name>Set Character Encoding</filter-name>
    <filter-class>filters.SetCharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>SJIS</param-value>
    </init-param>
  </filter>


  <!-- サーブレットの呼び出しフィルタのURLへのマッピング -->
  <filter-mapping>
    <filter-name>Servlet Mapped Filter</filter-name>
  <servlet-name>invoker</servlet-name>
  </filter-mapping>
  
  <filter-mapping>//フィルタのURLへのマッピングの宣言
    <filter-name>Path Mapped Filter</filter-name>//マッピングするフィルタ名
  <url-pattern>/servlet/*</url-pattern>//マッピングパターン
  </filter-mapping>


  <!-- キャラクタエンコーディングフィルタの全てのアドレス(/*)へのマッピング -->
  <filter-mapping>
    <filter-name>Set Character Encoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- WEBアプリケーションでのイベントリスナーの宣言 -->
  <listener>//リスナーの宣言
    <listener-class>listeners.ContextListener</listener-class>//リスナークラス
  </listener>
  <listener>
    <listener-class>listeners.SessionListener</listener-class>
  </listener>

  <!-- サーブレットの宣言 -->
  <servlet>//サーブレットの宣言
    <servlet-name>snoop</servlet-name>//サーブレットの宣言名
    <servlet-class>SnoopServlet</servlet-class>//上記サーブレットの宣言で利用するクラス名
    <init-param>//サーブレット内で利用する初期値
      <param-name>foo</param-name>//初期値の名称
      <param-value>bar</param-value>//初期値の値
    </init-param>
  </servlet>
  
  <servlet>
   <servlet-name>servletToJsp</servlet-name>
   <servlet-class>servletToJsp</servlet-class>
  </servlet>
  
  
  <!-- サーブレットのURLへのマッピング -->
  <servlet-mapping>
    <servlet-name>invoker</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>//サーブレットのURLへのマッピングの宣言
    <servlet-name>snoop</servlet-name>//マッピングするクラス名
    <url-pattern>/snoop</url-pattern>//マッピングパターン
  </servlet-mapping>
  
  <servlet-mapping>
    <servlet-name>servletToJsp</servlet-name>
    <url-pattern>/servletToJsp</url-pattern>
  </servlet-mapping>
  
  
  <!-- タグライブラリの宣言 -->
  <taglib>//タグライブラリの宣言
    <taglib-uri>http://jakarta.apache.org/tomcat/debug-taglib</taglib-uri>//タグライブラリのURIの設定
    <taglib-location>/WEB-INF/jsp/debug-taglib.tld</taglib-location>//TLDファイルの場所
  </taglib>

  <taglib>
    <taglib-uri>http://jakarta.apache.org/tomcat/examples-taglib</taglib-uri>
    <taglib-location>/WEB-INF/jsp/example-taglib.tld</taglib-location>
  </taglib>

</web-app>

 
     

なおServletAPI2.2ではfilterとlistenerの宣言は存在しません。重要なのは、まずサーブレット本体を宣言した後に、そのサーブレットのURLのマッピングを指定しているということです。このような実体とURI(もしくはURL)とのマッピングを別々に行う手法は良く見られます。この方法によりURLにより呼び出されるサーブレットを抽象化し、サーブレットクラス変更時のアプリケーションに対する変更を最小限にとどめることができます。またこれらの宣言の順番はDTDで厳密に決められており、宣言する順番を間違うとサーバーが起動しなかったり、コンテキストが初期化されなかったりしますので注意してください。

サンプルアプリケーション(コントローラーとサブコントローラー)sample.zip

 

 
↑上へ 目次へ戻る