(5)doPost()メソッド
「HttpServletクラスのdoPost()メソッドは、HTTPのPOSTメソッドでリクエストされた際に呼び出されます。Webページ上のフォームからの送信は通常POSTで行われますから、その際にこのメソッドが実行されるのです。処理としてはdoGet()メソッドとまったく同じです」
「ところでdoGet()メソッドもそうでしたけど、冒頭で@Overrideと書かなきゃならないんですか」
「@Overrideアノテーションは、オーバーライドしていることを示します。なくてもエラーにはなりませんが、メソッド名の入力ミスやパラメーターの設定に問題があるとコンパイラが通知してくれますので、付けておいた方がよいでしょう」
(6)processRequest()メソッド
「サーブレットで独自に定義しているメソッドです。このメソッドで、レスポンスデータを出力します。パラメーターのrequestとresponseは、先のdoGet()/doPost()と同じインターフェイス型です」
●(1)Content-Typeの設定
「出力の順序としては、コンテンツのタイプと文字コードをContent-Typeとして、レスポンスヘッダーに設定します。それからレスポンスボディとして、HTMLのヘッダー情報を出力し、実際にページとして表示されるbody要素を出力します。まず、Content-Typeの設定から見ていきましょう」
「setContentType()は、レスポンスヘッダーのContent-Typeフィールドを設定するメソッドです。WebサーバーはHTMLだけでなく、画像や動画など様々なデータをレスポンスとして送信しますよね。なので、ブラウザー側でレスポンスデータを適切に処理できるように、Content-Typeフィールドで示しておくのです」
「送信するデータの種類は『MIMEタイプ』で示すのですが、これはファイルシステムにおける拡張子と考えてもらえるといいです。MIMEタイプの『text/html』は、テキスト形式のHTMLであることを示します」
「なるほど。ところでsetContentType()って、HttpServletResponseインターフェイスのメソッドですか?」
「いえ、HttpServletResponseのスーパーインターフェイスであるServletResponseのメソッドです。このインターフェイスには、レスポンスデータを処理するための基本機能が用意されています」
ServletResponseインターフェイス | HttpServletResponseextendで拡張している |
---|---|
メソッド | 内容 | |
---|---|---|
setContentType() | MIMEタイプと文字エンコーディングを示すContent-Typeフィールドを設定する。 | |
setCharacterEncoding() | レスポンスボディで使用されている文字エンコーディング (MIME 文字セット) を示すContent-Encodingフィールドを設定する。 | |
getWriter() | 文字データをクライアントに送り返すのに使用するPrintWriter型のインスタンスを返す。 | |
getOutputStream() | レスポンスデータをバイナリとして出力する際に使用するServletOutputStream型のインスタンスを返す。 | |
flushBuffer() | バッファリングされているコンテンツを強制的にクライアントに出力する。 | |
getBufferSize() | レスポンスに設定されている実バッファサイズを返す。 | |
setLocale(Locale loc) | レスポンスのロケール情報を設定する。 | |
●(2)HTMLの出力
「レスポンスボディへ文字列を出力するには、java.io.PrintWriterクラスのインスタンスが必要です。PrintWriterクラスは、テキストを出力ストリームに出力する処理を行うクラスですが、ServletResponseインターフェイスのgetWriter()メソッドでこのクラスのインスタンスを取得することができます」
「newでインスタンス化するのではなく、getWriter()メソッドで取得するのですね」
「というのは、getWriter()で返されるインスタンスは、サーブレット専用のPrintWriterオブジェクトを返してくれるのです。たんにテキストを出力ストリームに出力するだけでなく、レスポンスボディに出力しこれを送信できるようにしたPrintWriterオブジェクトとしてです」
「で、何でまたtryブロックの( )の中で取得してるんですかね」
「processRequest()メソッドではthrowsで、ServletException例外とIOException例外を投げるようにしています。ServletExceptionはサーブレット固有のエラー、IOExceptionは入出力に関するエラーを扱うクラスなので、エラー発生時にそれぞれのクラスのインスタンスがメソッドに渡される(投げられる)ようにしてるのですね。で、例外が発生する可能性がある処理をtryブロックにまとめてあるわけです」
「出力処理をtryブロックにまとめたことはわかりましたが、問題はなぜPrintWriterのインスタンスをtryのあとの( )の中で取得しているのかってことですよ」
「これはですね、Java SE 6から採用された『try-with-resources』という、リソースを自動でクローズ(閉じる)させる機能を使うためです。というのは、PrintWriterで開いた出力ストリームは、処理が終わったあとclose()というメソッドで閉じなきゃならないんです。ですが、tryのあとの( )の中で生成したリソース――ここでは出力ストリームですね――は、処理が終わると自動でクローズするようになるのです」
「なーるほど、後処理を書かなくてもいいんだ」
「通常ですと、finallyブロックでclose()メソッドを実行する必要があるんですが、それが不要になるのでコードが簡潔になるわけです」
「で、あとは参照変数のoutを使ってHTMLの要素を出力していくんですね」
「PrintWriterクラスのprintln()メソッドで1行ずつ出力していきます。結果、ブラウザーには次のようなHTMLドキュメントが渡されます」
プロジェクトに必要なファイルやフォルダーは、プロジェクトの作成時に指定した領域に保存されます。操作例では、ユーザー専用のDocumentsフォルダー「C:\Users\ユーザー名\Documents\」以下の「NetBeansProjects」フォルダーに「ServletApp01」として保存されています。
プロジェクトをビルドすると、ソースファイルに記述されたソースコードのコンパイルとプログラムに必要なファイルへのリンクが行われます。ここまでが通常のビルドにおける処理ですが、このあとでアプリケーションサーバーで公開するために必要な処理としてデプロイが行われます。具体的には、Webアプリケーションに必要なファイルをWar形式のファイルにまとめます。War形式ファイルはzip圧縮された拡張子が「.war」のファイルです。で、作成されたWarファイルがGlassFishのシステム領域にコピーされることで、外部からアクセスできるようになります。
サーブレットクラスのソースファイルは「Servlet01.java」で、コンパイルが行われると「Servlet01.clss」としてディレクトリに( NetBeansProjects\ServletApp01\build\web\WEB-INF\classes\com\example )保存されます。
Warファイルは、プロジェクトのフォルダー内の「dist」フォルダーに保存されます。
Javaサーバサイドプログラミング パーフェクトマスター
金城俊哉著
秀和システム 3,780円
Javaははじめてですか? でも、しり込みしなくたっていいんです。いきなりサーバサイドからはじめましょう!
本書は、Webエンジニアを目指す人のために対話形式でJava
EEを基礎からストア構築まで動かしながら学べる解説書です。Javaサーブレットを学び、Java
EEを極めていく一方、初心者のためにコラム形式でJavaの基本も説明します。実行環境の構築、ロジックの作成、データベース連携まで動かしながら覚えられます!
Copyright © ITmedia, Inc. All Rights Reserved.