◆当サイトで人気のプログラミング教室のおすすめランキングはこちら!
プログラミングは独学では非効率で、時間を無駄にするリスクがあります。効率的なカリキュラムで学べるスクールを受講しましょう。

DMM WEBCAMP【マンツーマンサポート】1ヶ月短期集中でプログラミングを学ぶスクール
1ヶ月通い放題・メンター常駐の教室環境でプログラミングを学びたい方!
TechAcademyオンラインで開講しているプログラミングスクール
オンラインでどこでも学べる!/教室に行くのが忙しい人でも安心!
TECH::CAMP教養としてのITスキルを学べるスクール
Webデザイン/AI(人工知能)/IOS/Androidアプリ制作/VRを学びたい方!
DMM WEBCAMP PRO転職保証付き!エンジニアとして転職したい人におすすめ!
未経験からプロのエンジニアへ3ヶ月で転職する為のスクールです!
1月生募集中!当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のDMM WEBCAMP PROコース。
12月生は満員となっております。1月生募集に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい
上記にあてはまる方は、ぜひご検討ください!

みなさんは、Javaの学習を進めてはいませんか?

今回の記事では、Javaのプログラムの一つである「Java Servlet(サーブレット)」について解説していきます。

はじめに

 Javaサーブレットとは、Webブラウザなどからの要求に基づいて起動され、サーバ上で何らかの処理を行ったり、
動的にWebページを生成してクライアントに送信したりするサーバ側Javaプログラムのことです。

Webページの閲覧者の操作や入力に基いてサーバ側で処理を行い、結果を反映したページを送り返すことができ
アプリケーションソフトのように利用できるWebサイトを構築することができます。
このようなWebサイトを「Webアプリケーション」(Web application)といいます。

ここでは、サーブレットの作成を行う上で、用意されているクラスやメソッドの使い方、サーブレットの
ライフサイクルなどサーブレットの基本的な事項について確認をしていきます。

サーブレットの基本

サーブレットを作成する上で必要となるクラスが含まれているパッケージについて簡単に見ていきます。
大きくわけて2つのパッケージが用意されており、「javax.servlet」パッケージと「javax.servlet.http」パッケージがあります。

全てのサーブレットは「javax.servlet」パッケージに含まれる「Servlet」インターフェースを実装する必要があります。
このインターフェースを実装しているのが「GenericServlet」クラスと「HttpServlet」クラスです。
その為、通常はこのどちらかのクラスを継承してクラスを作成します。

「GenericServlet」クラスはプロトコルに依存しないサーブレットを作成する場合に利用します。
「HttpServlet」クラス自体も「GenericServlet」クラスのサブクラスですがHTTP通信を行うサーブレットを作成するのみ便利なように拡張されたクラスとなっています。
今回はHTTP通信を行うサーブレットを中心に利用方法を確認していきますので、基本的には「HttpServlet」クラスを継承して作成するようにします。

サーブレットを作成する上で継承して利用するクラスが「HttpServlet」クラスとなります。
「HttpServlet」クラスで用意されている様々なメソッドを定義していくことでサーブレットを作成していきます。

またサーブレットがクライアントであるブラウザなどから呼ばれた時にパラメータなどの情報が含まれているのが「HttpServletRequest」インターフェースのオブジェクトです。
そしてサーブレットからクライアントに出力を行う場合に利用するのが「HttpServletResponse」インターフェースのオブジェクトです。
これらは「HttpServlet」クラスの中で定義されているメソッドの引数として渡されてきます。

他にクッキーを扱う「Cookie」クラス、セッションを扱う「HttpSession」インターフェースなどがあります。

HttpServletクラスとメソッド

サーブレットの基本となる「HttpServlet」クラスを見てみます。

クラス定義

クラス定義は下記のようになっています。
サーブレットは「Servlet」インターフェースを実装する必要がありますが「GenericServlet」クラス で実装が行われているため
「GenericServlet」クラスのサブクラスとして「HttpServlet」クラスは定義されています。

java.lang.Object
javax.servlet.GenericServlet
javax.servlet.http.HttpServlet

public abstract class HttpServlet extends GenericServlet implements java.io.Serializable

 

java.lang.Object
javax.servlet.GenericServlet
javax.servlet.http.HttpServletpublic abstract class HttpServlet extends GenericServlet implements java.io.Serializable

メソッド

「HttpServlet」クラスでは多くのメソッドが定義されています。
リクエストのHTTPメソッドの種類毎に対応するメソッドがそれぞれ用意されています。

[GET] : protected void doGet(HttpServletRequest req, HttpServletResponse resp)
[POST] : protected void doPost(HttpServletRequest req, HttpServletResponse resp)
[PUT] : protected void doPut(HttpServletRequest req, HttpServletResponse resp)
[DELETE] : protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
[HEAD] : protected void doHead(HttpServletRequest req, HttpServletResponse resp)
[TRACE] : protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
[OPTIONS] : protected void doOptions(HttpServletRequest req, HttpServletResponse resp)

「HttpServlet」クラスを継承したクラスは、このどれかのメソッドを最低1つは実装する必要があります。
もし複数のHTTPメソッドで呼び出される可能性がある場合は複数のメソッドを実装することも可能です。

「GET」と「POST」

HTTPメソッドの中でも主に使われるのは「GET」と「POST」です。

「GET」メソッドはクライアントからページの要求を行う場合に使われます。
直接サーブレット名をURLに指定して表示したりリンクに設定されたサーブレットをクリックした場合には「GET」を使ってリクエストが来ます。
またフォームにおいて送信方法に「GET」を使った場合にも「GET」メソッドが使われます。

「POST」メソッドはクライアントからデータを送る場合に使われます。
主にフォームにおいて送信方法に「POST」を指定した場合に使われます。

サーブレット作成

ここではサーブレットの基本となるものを順に作っていきたいと思います。

HttpServletクラスの継承

HTTP通信を行うサーブレットは「HttpServlet」クラスを継承して作成します。

public class HelloWorld extends HttpServlet{
/* ... */
}

HTTPメソッドに対応したメソッドの実装

「HttpServlet」クラスを継承した場合は、「doGet」メソッド又は「doPost」メソッドを実装します。
例えばGETメソッドで呼ばれる可能性があるサーブレットであれば次のようになります。

public class HelloWorld extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/* ...  */
}
}

POSTメソッドで呼ばれる可能性があるサーブレットであれば次のようになります。

public class HelloWorld extends HttpServlet{
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/* ...  */
}
}

GETメソッドとPOSTメソッドの両方で呼ばれる可能性があるサーブレットであれば次のようになります。

public class HelloWorld extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/* ... */
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/* ... */
}
}

作成したサーブレットをブラウザなどから呼び出した時にGETメソッドで呼び出せば「doGet」メソッドの中に記述した処理が実行され
フォームなどから「POST」メソッドを使ってデータを送信した場合は「doPost」メソッドの中に記述した処理が実行されます。

doGetメソッドやdoPostメソッド内の処理の実装

「doGet」メソッドはクライアントからデータの要求がある場合に呼び出されます。
そこで「doGet」メソッド内にはクライアントに対して要求された内容を出力するような処理を記述します。
出力する場合にはメソッドの引数の1つである「HttpServletResponse」インターフェースのオブジェクトを利用します。

「doPost」メソッドはクライアントからデータが送られてくる場合に呼び出されます。
「doPost」メソッド内にはクライアントから送られてきた情報などを取得するような処理を記述します。
リクエストの内容を取得するにはメソッドの引数の1つである「HttpServletRequest」インターフェースのオブジェクトを利用します。

「doGet」メソッドでもフォームからデータを送信されてくることがありますし「doPost」メソッドでも結果をブラウザに返す
必要がありますので結果的にはこの2つのメソッドで大きな使い方の違いはありません。
あくまでリクエストのHTTPメソッドの種類に応じて分けられていると考えてもいいかと思います。

結果的にサーブレットは次のようになります。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{

response.setContentType("text/html");
PrintWriter out = response.getWriter();

out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
out.close();
}
}

サーブレットのライフサイクル

サーブレットはTomcatなどのサーブレットが動作するコンテナが起動してから最初にサーブレットが呼ばれたときにコンテナにロードされインスタンスが作成されます。

サーブレットはリクエストに対してスレッドを作成し、そのスレッドが実際の処理を行います。
複数のリクエストが同時にあればそれぞれ別のスレッドが用意されマルチスレッドで動作することになります。

スレッドはリクエストに対する処理が終われば終了しますがインスタンスはそのまま残っており新しいリクエストが来れば新しいスレッドを作成して実行します。
そのため2回目以降はインスタンスを作成する時間がかかりません。

コンテナが終了したり一定時間サーブレットに対してアクセスが無かった場合にインスタンスは破棄されます。

サーブレットの作成から破棄までの流れは以上のようになっており、初回と最後以外はインスタンスがある状態で実行され、同じインスタンスが共有して利用されるようになっています。

インスタンス変数

サーブレットはリクエストがあるたびにスレッドが用意されて実行されますが、インスタンスに含まれるスレッドで共有される変数を作成することが出来ます。
これをインスタンス変数といいます。

インスタンス変数はクラス内に記述され、特定のメソッドの外側に記述されている変数です。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Sample extends HttpServlet {

int count = 0;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{

int l_count = 0;
}
}

上記の中で「count」がインスタンス変数です。
この変数は全てのスレッドで共有して利用される変数ですので、同じ変数に対して別々のスレッドがそれぞれ参照
したり値を変更したりする事が出来ます。

それに対して「doGet」などのメソッド内に記述されたローカル変数(ここでは「l_count」)はスレッド毎に独立していますのであるスレッドのローカル変数に別のスレッドがアクセスすることは出来ません。

例えばカウンターの値などスレッド全体で共有できる値を持つことが出来る反面、何か処理をしている途中で別のスレッドから値を書き換えられるようなケースも考えられるためインスタンス変数を使う場合には注意が必要です。
またインスタンス変数は、インスタンスが終了すれば破棄されてしまいます。

インスタンス変数の初期化は、頻繁に実行されるdoGetメソッド内などで実行すると、スレッドが新しく作られるたびに行われてしまいますので問題が起きてしまいます。そこで上記のように変数宣言時に行うか、インスタンスが作成される時に一度だけ実行される「init」メソッド内で行います。

initメソッドとdestoryメソッド

サーブレットのライフサイクルについて説明しましたが、サーブレットのインスタンスが作成された後、そして破棄される前にそれぞれ
特定のメソッドを呼びだすことが出来ます。

initメソッド

インスタンスが作成された後で実際の処理が行われる前に呼び出されるのが「init」メソッドです。
最初のリクエストに対してスレッドが作成され実際の処理が行われる前に呼び出されることが保証されています。
その為、インスタンス自体に対して初期化するような処理を記述するのに利用されます。

「init」メソッドは「HttpServlet」クラスの親クラスである「GenericServlet」クラスで定義されています。

public void init() throws ServletException

実際の使い方としては次のような感じとなります。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Sample extends HttpServlet {
public void init() throws ServletException{
/* 初期化処理 */
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/* ... */
}
}

destroyメソッド

サーブレットが破棄される前に呼び出されるのが「destroy」メソッドです。インスタンス変数の値をファイルに書き出したり、
インスタンスで共有していたデータベース接続の切断処理を行ったりといった処理を行うのに使います。

「destroy」メソッドは「HttpServlet」クラスの親クラスである「GenericServlet」クラスで定義されています。

public void destroy()

実際に使う場合には「destroy」メソッドをオーバーライドして処理したい内容を記述します。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Sample extends HttpServlet {
public void init() throws ServletException{
/* 初期化処理 */
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/* ... */
}

public void destroy(){
/* 終了処理 */

}
}

さいごに

いかがだったでしょうか。
Javaをローカルで動作させているのとは違い、サーバ側での動作を主とするサーブレットは
少々とっつきにくいかもしれませんが、JavaとWEBアプリケーションを語る上で外せない内容ですので
今回の内容を基本としてサーブレットに触れてみてくださいね。

WebCamp・Webスクについて

DMM WEBCAMPは1ヶ月でプログラミング・WEBデザインを学ぶ通い放題のプログラミングスクールです。DMM WEBCAMP PROは3ヶ月間で未経験から即戦力エンジニアを育成する転職保証付きのプログラミングスクールです。

2つのサービスを運営するインフラトップでは、「学びと仕事を通して人生を最高の物語にする」という理念で会社を経営しています。

キャリアアップを目指す方は、この機会に私達と一緒にプログラミングを学んでみませんか?

1月枠も残りわずか当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のDMM WEBCAMP PROコース。
12月受入枠は満員となっております。1月枠に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい
上記にあてはまる方は、ぜひご検討ください!

▼未経験から1ヶ月でWEBデザイン・プログラミングを学びたい方はこちら!


▼ついに開講!オンラインでWEBデザイン・プログラミングを学びたい方はこちら!

おすすめの記事