ユーザーがブラウザで入力したデータを処理して返す
サーブレットの基本形がわかったところで,もう少しWebアプリケーションらしくしてみましょう。リスト1はブラウザから入力データを受け取っていないため,リクエストの処理が存在しません。また,ブラウザに返すデータも,コンテント・タイプの指定やタグがない素の文字列だけで,あまりにそっけなさすぎます。
そこで,ブラウザから入力されたデータを処理し,その結果をWebページの形で返すように改造します(図3[拡大表示],sample1)。入力画面のHTMLをリスト2[拡大表示]に示しました。ユーザーが入力フォームに文字を入れて「メッセージを送る」と書かれたボタンを押すと,messageという名前の文字列のデータがShowMessageというサーブレットに送られます。formタグのmethod属性はpostと指定しています。
ShowMessageサーブレットのコードはリスト3[拡大表示]です。リスト1ではdoGetメソッドをオーバーライドしていたのに対し,今度はdoPostメソッドをオーバーライドしています。これらの違いは何でしょう。
実は,doGetの「Get」とdoPostの「Post」は,HTTPの仕様で決められている2種類のリクエストの送り方,「GETメソッド」と「POSTメソッド」をそれぞれ表しています。これらはJavaのメソッドとは意味が違いますので注意してください。HTTPのGETメソッドで送られてくるリクエストを処理するのがサーブレットのdoGetメソッド,POSTメソッドで送られてくるリクエストを処理するのがdoPostメソッドです。ややこしいですね。
GETメソッドは,ブックマーク,リンク,URLの指定などによる通常のWebアクセスの際にリクエストを送る方式です。formタグでmethod属性にgetを指定すると,ユーザーがフォームに入力したデータもGETメソッドで送ることができます(図4[拡大表示])。この場合,URLにデータが埋め込まれます*5。一方,formタグでmethod属性にpostを指定すると,フォームのデータはPOSTメソッドで送られます。データはリクエスト・メッセージの本体であるメッセージ・ボディに格納されます。
GETメソッドによるフォーム・データの送信は,検索系のサイトでよく使われています。検索結果のページのURLに検索キーが埋め込まれるので,ブックマークしたりリンクを張ったりできるからです。ただ,GETメソッドでは,送るデータが多くなるにつれてURLが長くなってしまいます。アンケートの入力ページなど,URLにデータを残す必要がない場合はPOSTメソッドを使用します。
GETとPOSTの違いがわかったところでリスト3に戻りましょう。まず,ブラウザから送られたリクエストの処理です。リクエスト・オブジェクトのsetCharacterEncodingメソッドで,文字コードをシフトJISに指定します*6。この指定をしないと正しい文字コードでデータを受け取れず,フォームで日本語を入力して送信した場合に文字化けが起こるので注意してください。フォームの入力データを受け取るメソッドがgetParameterです。このメソッドはStringオブジェクトを返します。
リクエストの処理が終わったら,ブラウザに返信するレスポンスの処理を行います。HTMLとして返信するには,コンテント・タイプの指定が必要です。レスポンス・オブジェクトのsetContentTypeメソッドで指定します。表示するWebページの文字コードも同時に指定しています。
今回は,PrintWriterオブジェクトに出力する内容にHTMLタグを追加し,きちんとしたWebページにしています。WebブラウザはHTMLタグの部分を解釈して表示します。一つのprintlnメソッドにHTMLをすべて記述すると見にくくなるので,適当に分割して記述するのが普通です。取得したStringオブジェクトをHTMLのコードの中に埋め込めば,Webページにユーザーが入力したメッセージが表示されるようになります。
セッション・オブジェクトを利用し
複数のWebページで情報を共有
ただ,これだけではまだ,Webアプリケーションを実現する既存の仕組みであるCGIとさほど違いはありません。サーブレットを利用するメリットは,Webアプリケーションの構築に便利な様々な機能があらかじめ備わっている点にあります。
中でも重要なのが,セッション管理の機能です*7。HTTPは,1回のアクセスごとにセッションが完結するという性質を持っています。このため,そのままでは複数のWebページで情報を共有することができません。CGIで複数ページにわたって情報を共有するには,セッションの情報を保存しておく何らかの仕組みをプログラマが作り込む必要がありました。
これに対してサーブレットには,ユーザー単位のセッションを表す「セッション・オブジェクト」があらかじめ用意されています。ユーザーがWebサイトにアクセスしている間は,ユーザーごとにセッション・オブジェクトが自動的に保持されます*8。ここにデータを貼り付けておくだけで,異なるWebページの間でデータを共有できるのです*9。セッション・オブジェクトは,ユーザーがブラウザを終了するか,セッションを共有しているWebページに一定時間アクセスしないと自動的に破棄されます*10。
セッション・オブジェクトの動作を確認するため,Webブラウザで入力したデータをリンク先のページに表示するサンプルを用意しました(図5[拡大表示],sample2)。最初にアクセスするShowMessageサーブレットで入力データをセッション・オブジェクトに貼り付けます。ShowMessageからリンクで飛ぶShowSecondサーブレットで,セッション・オブジェクトから入力データを取り出して表示しています。
セッションを扱えるように改造したShowMessageがリスト4[拡大表示]です。getSessionは,セッション・オブジェクトを取得するためのメソッドです。引数に「true」を指定すると,セッション・オブジェクトが存在しない場合には新たに作られます。「false」を指定した場合は,セッション・オブジェクトがなくても生成されません。
保存しておきたいオブジェクトをセッション・オブジェクトに貼り付けるメソッドがsetAttributeです。ここでは「message」という名前で入力データのStringオブジェクトを貼り付けています。
ShowSecondサーブレットでは,セッションから必要なデータを取り出しています(リスト5[拡大表示])。まず,getSessionメソッドで,すでにあるセッション・オブジェクトを呼び出しています。ここではセッション・オブジェクトを生成する必要はないのでfalseを指定しています*11。
次にgetAttributeメソッドで「message」という名前が付いたオブジェクト,すなわちユーザーがブラウザで入力したデータを取得しています。Stringオブジェクトとして取り出すために,String型でキャストしています*12。このデータをHTMLに組み込んで表示しています。