3 サーブレットの作成と構成
この章の内容は以下のとおりです。
サーブレットの新機能と変更された機能
これらの項では、サーブレット3.1と3.0との間のサーブレット・プログラミングのモデルおよび要件に関する変更点をまとめています。
サーブレット3.1の新機能と変更された機能
WebLogic Serverでは、サーブレット3.1仕様(http://jcp.org/en/jsr/detail?id=340を参照)をサポートしています。この仕様では、次の新機能が導入されています。
-
非ブロッキングI/Oの読取りまたは書込みのために追加されたサポート—サーブレット3.0では非同期リクエスト処理が可能でしたが、従来のI/Oのみが許可されていました。これは、クライアント・リクエストに関連するスレッドが入出力を考慮してアイドル状態になる可能性があるため、アプリケーションのスケーラビリティが制限されていました。サーブレット3.1は、リスナーの読取りおよび書込みの非ブロッキングI/Oをサポートし、これにより、スケーラブルなアプリケーションを作成できます。
-
HTTPプロトコル・アップグレード処理—HTTP/1.1によって、クライアントはサポートしている通信プロトコルの中で使用したいものを指定できます。サーブレット3.1は、サーブレット内でHTTPプロトコル・アップグレード機能をサポートします。
-
カバーされていないHTTPメソッドを処理することによるセキュリティの拡張—
deny-uncovered-http-methods
フラグはアプリケーションのweb.xml
ファイルで設定することができます。この設定により、HTTPメソッドがリクエストURLに最適なURLパターンに適用される組み合されたセキュリティ制限でカバーされないリクエストURLとともに使用される際、コンテナはすべてのHTTPプロトコル・メソッドを否認します。 -
新しいJava EE 7サーブレット・サンプル—WebLogic Serverをサンプル付きで完全にインストールすると、ソース・コードのサンプルが
EXAMPLES_HOMEexamples\src\examples
ディレクトリに置かれます。デフォルトのパスはORACLE_HOME\wlserver\samples\server
です。このディレクトリから、サンプル・ドメインを設定することなくソース・コードおよびServlet 3.1サンプルの手順ファイルにアクセスできます。ORACLE_HOME\user_projects\domains\wl_serverディレクトリには、WebLogic Serverのサンプル・ドメインが含まれています。このドメインには、アプリケーション、アプリケーションおよびOracle WebLogic Serverの動作方法を定義するXML構成ファイル、および起動スクリプトと環境スクリプトが含まれます。WebLogic Serverサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項 を参照してください。
-
HTTPプロトコル・アップグレードAPIの使用 – クライアントが追加の通信プロトコルを指定できるようにするHTTPプロトコル・アップグレードAPIの使用方法を示します。
EXAMPLES_HOME/examples/src/examples/javaee7/servlet/http-upgrade
-
非ブロッキングI/O ReadListenerの使用 – 非ブロッキングの方法でリクエストから読み取るサーブレットでの
ReadListener
インタフェースの使用方法を示します。EXAMPLES_HOME/examples/src/examples/javaee7/servlet/non-blocking-io-read
-
非ブロッキングI/O WriteListenerの使用 – 非ブロッキングの方法でリクエストに書き込むサーブレットでの
WriteListener
インタフェースの使用方法を示します。EXAMPLES_HOME/examples/src/examples/javaee7/servlet/non-blocking-io-write
-
セッションIDの変更 –
HttpServletRequest
APIを使用してセッションIDを変更する方法を示します。EXAMPLES_HOME/examples/src/examples/javaee7/servlet/session-id-change
-
カバーされていないHTTPメソッドの処理 – カバーされていないHTTPメソッドを否認する方法を示します。
EXAMPLES_HOME/examples/src/examples/javaee7/servlet/uncovered-http-method
-
サーブレット3.0の新機能と変更された機能
サーブレット3.0仕様(http://jcp.org/en/jsr/detail?id=315
を参照)では、次の機能が導入されています。
-
非同期処理—サーブレットは、データベースなどのリソースからのレスポンスを待機しなくても、そのスレッドを続行できるようになりました。つまり、スレッドはブロックされません。
-
Webモジュールのデプロイメント記述子フラグメント(Webフラグメント)—
web-fragment.xml
ファイルでは、WEB-INF/lib
の下にパッケージされているライブラリJARの接続性が拡張されています。Webフラグメントとは、ライブラリまたはフレームワークJARのMETA-INF
ディレクトリ内に指定して組み込むことができるweb.xml
ファイルの一部または全部のことです。 -
新しいJava EE 6サーブレット・サンプル—WebLogic Serverをサンプル付きで完全にインストールすると、ソース・コードのサンプルが
EXAMPLES_HOME\examples\src\examples
ディレクトリに置かれます。デフォルトのパスはORACLE_HOME\wlserver\samples\server
です。このディレクトリから、サンプル・ドメインを設定することなくソース・コードおよびServlet 3.0サンプルの手順ファイルにアクセスできますORACLE_HOME\user_projects\domains\wl_server
ディレクトリには、WebLogic Serverのサンプル・ドメインが含まれています。このドメインには、アプリケーション、アプリケーションおよびOracle WebLogic Serverの動作方法を定義するXML構成ファイル、および起動スクリプトと環境スクリプトが含まれます。WebLogic Serverサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項 を参照してください。-
サーブレット、フィルタおよびリスナーのアノテーションの使用 – web.xml記述子内での定義およびマッピング・エントリを必要とすることなく、Webアプリケーション・コンポーネントをアノテーション(
@WebServlet
、@WebListener
および@WebFilter
など)からのみ定義する方法を示します。EXAMPLES_HOME/examples/src/examples/javaee6/servlet/annotation
-
非同期サーブレットおよびリクエスト処理 – サーブレットが非同期リクエストを処理できるとマーク付けされているサーブレット3.0の非同期処理を示します。
EXAMPLES_HOME/examples/src/examples/javaee6/servlet/asyncServlet30
-
マルチパート・ファイルを使用したファイル・アップロードの処理 – ブラウザ・クライアントからのファイルのアップロードを処理する
@MultipartConfig
アノテーションの使用を示します。EXAMPLES_HOME/examples/src/examples/javaee6/servlet/multipartFileHandling
-
プログラムによるセキュリティの使用 –
HttpServletRequest
インタフェースの新しいlogin()
メソッドおよびauthenticate()
メソッドの使用を示し、これによりアプリケーションはプログラムによってセキュリティを制御できることを示します。EXAMPLES_HOME/examples/src/examples/javaee6/servlet/programmaticSecurity
-
サーブレットWebフラグメント – モジュール形式の自己完結型拡張機能をWebアプリケーションに簡単に追加できるサーブレット3.0のプラガブルな特性を示します。
EXAMPLES_HOME/examples/src/examples/javaee6/servlet/webFragment
-
ノート:
WebLogic Server 12.1.3以降は、サーブレット3.1仕様で定義されている標準アノテーションが推奨され、WebLogic Server固有のアノテーション(@WLServlet、
@WLFilterおよび
@WLInitParam)は非推奨となり、将来のリリースで削除されます。また、
weblogic.servlet.http.AbstractAsyncServlet
のかわりに、サーブレット3.1仕様で定義されている標準非同期処理モデルを使用してください。サーブレット3.1の非同期処理の構成の詳細は、「web.xmlデプロイメント記述子の要素」の「async-descriptor」を参照してください。
サーブレットの構成
Java EEメタデータ・アノテーションとデプロイメント記述子を使用してサーブレットを構成する方法、およびWebアプリケーションでサーブレット・マッピングを使用する方法を学習します。
サーブレット・アノテーション
Java EEメタデータ・アノテーションを使用すれば、標準のweb.xml
デプロイメント記述子は省略可能です。サーブレット仕様では、サーブレット、フィルタ、リスナー、タグ・ハンドラなどの特定のWebコンポーネントでアノテーションを定義できると規定されています。アノテーションを使用すると、外部リソースに対する依存関係を宣言できます。コンテナはこれらのコンポーネントのアノテーションを検出し、コンポーネントのライフサイクル・メソッドが呼び出される前に必要な依存関係を注入します。「Webコンポーネント用のWebLogicアノテーション」を参照してください。
ただし、サーブレットは、標準のWebアプリケーション・デプロイメント記述子web.xml
の複数のエントリでWebアプリケーションの一部として定義することもできます。web.xml
ファイルは、WebアプリケーションのWEB-INF
ディレクトリにあります。
web.xml
のルートservlet
要素の下の最初のエントリには、サーブレットの名前が定義され、そのサーブレットを実行するコンパイル済みクラスが指定されます。あるいは、サーブレット・クラスを指定するかわりに、JSPを指定することもできます。servlet
要素には、サーブレットの初期化属性とセキュリティ・ロール用の定義も含まれています。
web.xml
内のservlet-mapping
要素の下の2番目のエントリには、このサーブレットを呼び出すURLパターンが定義されています。
サーブレット・マッピング
サーブレット・マッピングとは、サーブレットへのアクセス方法を制御することです。次の例は、Webアプリケーションでサーブレット・マッピングを使用する方法を示しています。これらの例には、(web.xml
デプロイメント記述子の)サーブレット構成とマッピングのセットがあり、その後にこれらのサーブレットの起動に使用するURLを示す表(表3-1を参照)があります。
例3-1 サーブレット・マッピングの例
<servlet> <servlet-name>watermelon</servlet-name> <servlet-class>myservlets.watermelon</servlet-class> </servlet> <servlet> <servlet-name>garden</servlet-name> <servlet-class>myservlets.garden</servlet-class> </servlet> <servlet> <servlet-name>list</servlet-name> <servlet-class>myservlets.list</servlet-class> </servlet> <servlet> <servlet-name>kiwi</servlet-name> <servlet-class>myservlets.kiwi</servlet-class> </servlet> <servlet-mapping> <servlet-name>watermelon</servlet-name> <url-pattern>/fruit/summer/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>garden</servlet-name> <url-pattern>/seeds/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>list</servlet-name> <url-pattern>/seedlist</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>kiwi</servlet-name> <url-pattern>*.abc</url-pattern> </servlet-mapping>
表3-1 url-patternと呼び出されるサーブレット
URL | 呼び出されるサーブレット |
---|---|
http://host:port/mywebapp/fruit/summer/index.html |
watermelon |
http://host:port/mywebapp/fruit/summer/index.abc |
watermelon |
http://host:port/mywebapp/seedlist |
list |
http://host:port/mywebapp/seedlist/index.html |
デフォルト・サーバー(構成されている場合)、またはHTTP 404エラー・メッセージ(「File not found」)。
|
http://host:port/mywebapp/seedlist/pear.abc |
kiwi listサーブレットが |
http://host:port/mywebapp/seeds |
garden |
http://host:port/mywebapp/seeds/index.html |
garden |
http://host:port/mywebapp/index.abc |
kiwi |
ServletServlet
は、サーブレットのデフォルト・マッピングの作成に使用できます。たとえば、http://host:port/web-app-name/myservlet/com/foo/FooServlet
を使用してサーブレットを呼び出せるように/myservlet/*
に対するすべてのサーブレットにマップするデフォルト・マッピングを作成するには、web.xml
ファイルに以下の部分を追記します。(web.xml
ファイルは、WebアプリケーションのWEB-INF
ディレクトリにあります。)
<servlet> <servlet-name>ServletServlet</servlet-name> <servlet-class>weblogic.servlet.ServletServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletServlet</servlet-name> <url-pattern>/myservlet/*</url-pattern> </servlet-mapping>
デフォルト・サーブレットの設定
各Webアプリケーションには、デフォルト・サーブレットがあります。このデフォルト・サーブレットは管理者が指定できますが、指定しない場合、WebLogic ServerではFileServlet
という内部サーブレットがデフォルト・サーブレットとして使用されます。
どのサーブレットでも、デフォルト・サーブレットとして登録できます。独自のデフォルト・サーブレットを作成すれば、独自のロジックを使用して、デフォルト・サーブレットに送られるリクエストの処理方法を定義できます。
設定したデフォルト・サーブレットは、FileServlet
に取って代わります。FileServlet
はほとんどのファイル(テキスト・ファイル、HTMLファイル、イメージ・ファイルなど)を提供するために使用されるので、デフォルト・サーブレットの設定は注意深く行う必要があります。デフォルト・サーブレットでこれらのファイルを提供するには、その機能をデフォルト・サーブレットに記述する必要があります。
ユーザー定義のデフォルト・サーブレットを設定するには:
-
「クライアントによるWebアプリケーションへのアクセス方法の構成」の説明に従い、サーブレットを定義します。
-
次のように、servlet-mappingにurl-pattern = "
/
"を付けて追加します。<servlet-mapping> <servlet-name>MyOwnDefaultServlet</servlet-name> <url-pattern>/myservlet/*(</url-pattern> </servlet-mapping>
-
FileServlet
で他の拡張子付きのファイルを提供する場合は、次の手順に従います。-
サーブレットを定義し、
myFileServlet
などの<servlet-name>
を指定します。 -
<servlet-class>
をweblogic.servlet.FileServlet
と定義します。 -
<servlet-mapping>
要素を使ってファイル拡張子をmyFileServlet
にマップします(デフォルト・サーブレット用のマッピングに追加して)。たとえば、myFileServlet
で.gifファイルを提供するには、*.gif
をmyFileServlet
にマップします。ノート:
docHome
パラメータ(このリリースで非推奨になった)が指定されていない場合、ソース・ファイル名決定時のFileServlet
には、SERVLET_PATH
が含まれています。そのため、FileServlet
を/dir/*などにマップすることで、特定のディレクトリからのファイルのみを明示的に提供できます。
-
サーブレット初期化属性
サーブレットの初期化属性は、Webアプリケーションのデプロイメント記述子web.xml
の中のservlet
要素のinit-param
要素に、param-name
タグとparam-value
タグを使って定義します。web.xml
ファイルは、WebアプリケーションのWEB-INF
ディレクトリにあります。
たとえば:
例3-2 web.xml内のサーブレット初期化属性の構成例
<servlet> <servlet-name>HelloWorld2</servlet-name> <servlet-class>examples.servlets.HelloWorld2</servlet-class> <init-param> <param-name>greeting</param-name> <param-value>Welcome</param-value> </init-param> <init-param> <param-name>person</param-name> <param-value>WebLogic Developer</param-value> </init-param> </servlet>
単純なHTTPサーブレットの記述
Hello World
.というメッセージを出力する単純なHTTPサーブレットを記述する手順について検討します。
これらのステップを示すサンプル・コード(HelloWorldServlet
)の全文がこの項の最後にあります。JDBC、RMI、JMSなど各種のJava EEおよびWebLogic Serverサービスをサーブレットで使用する方法の詳細は、このドキュメントで後述します。
-
以下の適切なパッケージおよびクラスをインポートします。
import javax.servlet.*; import javax.servlet.http.*; import java.io.*;
-
javax.servlet.http.HttpServlet
を機能拡張します。たとえば:public class HelloWorldServlet extends HttpServlet{
-
service()
メソッドを実装します。サーブレットの主要な機能は、WebブラウザからのHTTPリクエストを受け取って、HTTPレスポンスを戻すことです。この処理は、サーブレットの
service()
メソッドによって行われます。サービス・メソッドには、出力を生成するレスポンス・オブジェクトと、クライアントからのデータを受け取るリクエスト・オブジェクトがあります。ほかにも、
doPost()
メソッドまたはdoGet()
メソッドを実装したサーブレットのサンプルを見たことがあるかもしれません。これらのメソッドは、POSTまたはGETリクエストにのみ応答するものです。service()
メソッドを実装しておけば、1つのメソッドですべてのリクエスト・タイプを処理できます。(ただし、service()
メソッドを実装する場合、service()
メソッドの最初でsuper.service()
を呼び出さない限り、doPost()
メソッドまたはdoGet()
メソッドを実装することはできません。)HTTPサーブレットの仕様には、他のリクエスト・タイプの処理に使用される他のメソッドも記述されていますが、これらのメソッドは全部まとめてserviceメソッドと総称されています。サービス・メソッドはすべて、同じパラメータ引数を取ります。
HttpServletRequest
は、リクエストの情報を提供し、HttpServletResponse
はHTTPクライアントに応答する際にサーブレットによって使用されます。サービス・メソッドは次のようになります。public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
-
次のように、コンテンツ・タイプを設定します。
res.setContentType("text/html");
-
次のように、出力に使用する
java.io.PrintWriter
オブジェクトへの参照を取得します。PrintWriter out = res.getWriter();
-
次の例に示すように、
PrintWriter
オブジェクトに対しprintln()
メソッドを使用して、HTMLを生成します。out.println("<html><head><title>Hello World!</title></head>"); out.println("<body><h1>Hello World!</h1></body></html>"); } }
-
サーブレットを次のようにコンパイルします。
-
開発環境シェルの設定を、クラスパスとパスを正しく指定して行います。
-
サーブレットのJavaソース・コードが格納されているディレクトリから、サーブレットが格納されているWebアプリケーションの
WEB-INF/classes
ディレクトリに、サーブレットをコンパイルします。たとえば:javac -d /myWebApplication/WEB-INF/classes myServlet.java
-
-
WebLogic ServerにホストされるWebアプリケーションの一部として、サーブレットをデプロイします。
-
ブラウザからサーブレットを呼び出します。
サーブレットの呼出しに使用するURLは、以下によって決まります。
-
そのサーブレットを含むWebアプリケーションの名前、および
-
Webアプリケーションのデプロイメント記述子にマップされるサーブレットの名前。リクエスト・パラメータも、サーブレットを呼び出すURLに含まれます。
一般的には、サーブレットのURLは以下のパターンに従います。
http://host:port/webApplicationName/mappedServletName?parameter
URLの各要素は次のように定義します。
-
host
は、WebLogic Serverが稼動しているマシンの名前。 -
port
は、上記マシンがHTTPリクエストをリスニングしているポート。 -
webApplicationName
は、サーブレットが含まれるWebアプリケーションの名前。 -
parameter
は、サーブレットで使用できるブラウザから送信された情報が含まれる、1つまたは複数の名前と値の組み合わせ。
たとえば、
examplesWebApp
にデプロイされ、使用中のマシンで稼動しているWebLogic Serverから提供されるHelloWorldServlet
(このドキュメントで使われているサンプル)をWebブラウザで呼び出す場合、次のようなURLを入力します。http://localhost:7001/examplesWebApp/HelloWorldServlet
URLの
host:port
部分は、WebLogic ServerにマップされているDNS名に置き換えることもできます。 -
高度な機能
基本的なサーブレットを作成するステップについて検討します。サーブレットでは、さらに高度な機能を使用することもできます。
-
HTML形式のデータ処理 - HTTPサーブレットでは、ブラウザ・クライアントからのHTMLフォームによるデータを受け取り、処理できます。
-
アプリケーションの設計 - HTTPサーブレットでは、様々な方法でアプリケーションを設計できます。サーブレットの記述に関する詳細は、次の項を参照してください。
-
サーブレットの初期化 - サーブレットの初期化時に、データを初期化する、初期化引数を受け取るなどのアクションを実行する必要がある場合は、
init()
メソッドをオーバーライドできます。 -
サーブレットにおけるセッションおよび永続性の使用 - セッションと永続性により、HTTPセッション中、およびHTTPセッション間でユーザーを追跡できます。セッション管理には、Cookieの使用も含まれます。次の項を参照してください。
-
サーブレットにおけるWebLogicサービスの使用 - WebLogic Serverが提供する様々なサービスやAPIをWebアプリケーションで使用できます。サービスには、Java Database Connectivity (JDBC)ドライバ、JDBCデータベース接続プール、Java Messaging Service (JMS)、Enterprise JavaBeans (EJB)、Remote Method Invocation (RMI)などがあります。次の項を参照してください。
HelloWorldServletサンプルの全文
前述の手順で使用したサンプルJavaソース・コードの全文について検討します。このサンプルはHTTPリクエストにレスポンスする簡単なサーブレットです。
このドキュメントの後半では、このサンプルを拡張することにより、HTTPパラメータ、Cookie、およびセッション・トラッキングの使用方法を説明します。
例3-3 HelloWorldServlet.java
import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class HelloWorldServlet extends HttpServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { // Must set the content type first res.setContentType("text/html"); // Now obtain a PrintWriter to insert HTML into PrintWriter out = res.getWriter(); out.println("<html><head><title>" + "Hello World!</title></head>"); out.println("<body><h1>Hello World!</h1></body></html>"); } }
サンプルをコンパイルおよび実行するためのソース・コードおよび手順は、WebLogic Server配布キットのORACLE_HOME\wlserver\samples\server\examples\src\examples\splitdir\helloWorldEar
ディレクトリ内にあります。この場合、ORACLE_HOME
は、WebLogic Serverがインストールされているディレクトリを表します。WebLogic Serverサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。
サーブレット・コンテナのデバッグ
WebLogic Serverサーブレット・コンテナで利用可能なデバッグ・オプションについて学習します。
アクセス・ロギングの無効化
サーブレットのアクセスのロギングは、サーバーのパフォーマンスに関してはコスト高となる場合があります。したがって、アクセス・ロギングが不要な場合は、アクセス・ログ・ファイルへのロギングを無効化することによりパフォーマンスを向上できます。
使用方法
weblogic.xml
のcontainer-descriptor
で指定可能なaccess-logging-disabled
プロパティは、基底のWebアプリケーションのアクセス・ロギングを無効化するかどうか指定する際に使用することができます。
-
このプロパティを
true
に設定すると、アプリケーション・アクセスはロギングされません。 -
このプロパティを指定しないか、
false
に設定すると、アプリケーション・アクセスがロギングされます。ノート:
disable-access-logging
プロパティは、Webアプリケーション・レベルで機能します。したがって、このプロパティを1つのWebアプリケーションで定義しても、他のWebアプリケーションには影響しません。このプロパティは、開発モードと本番モードの両方で機能します。ノート:
内部アプリケーションのロギングを無効にするには、このプロパティ
weblogic.servlet.logging.LogInternalAppAccess=false
を使用します。
例
次に、アクセス・ロギングを無効化する方法の例を示します。
<?xml version="1.0" encoding="ISO-8859-1"?> <weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"> <container-descriptor> <access-logging-disabled>true</access-logging-disabled> </container-descriptor> </weblogic-web-app>
特定セッションのデバッグ
セッション変化の追跡は、特にレプリケートされるセッションに関して、アプリケーションの開発時に大いに役立ちます。HttpSessionAttributeListener
を利用すると、セッションの変化をWebアプリケーション・レベルで追跡できますが、開発者は、特定のリクエスト時にセッション変化を追跡するため、より詳細なデバッグ・オプションを指定する必要があります。
使用方法
wl_debug_session
リクエスト属性または同じ名前のセッション属性は、現在のセッションにおける属性の変化をロギングすることができます。いずれかのフラグを使用すると、基底のセッションの変更がコンテナによってサーバー・ログに記録されます。
以下のいずれかの方法で特定セッションのデバッグを有効化することができます。
-
次に示すように、
wl_debug_session
属性を現在のセッションに設定します。 -
session.setAttribute('wl_debug_session', Boolean.TRUE);
-
wl_debug_session
属性を、リクエスト問合せ文字列でインジケータとして使用します。wl_debug_session
セッション属性は、コンテナにより現在のセッションに追加されます。次の例を参照してください。http://localhost/foocontext/foo?wl_debug_session
セッションのデバッグを停止するには、単にwl_debug_session
属性を削除します。
ノート:
この機能は開発モードでのみ使用できます。デバッグ・メッセージの重大度は、debug
レベルです。システム・ロガーがデバッグ・メッセージをサーバー・ログ・ファイルに出力できるように、ロガーの重大度はdebug
以下に調整する必要があります。