Servlet/JSP 応用編01 マルチスレッド
はじめに
僕たちの使うWebサイトは、複数人のユーザが同時に使用することが普通である。そのため、起動されたサーブレットのインスタンスは、同時に複数のユーザに利用される可能性が高い。そこで、サーブレットはマルチスレッドを使い、複数のユーザに対するリクエストを、平行に処理する。
問題点
マルチスレッドで動作することを考慮したマルチスレッドプログラミングでは問題点があり、それは、ある特定の変数を複数のスレッドが同時に操作する可能性があるということである。
例としては、一つのカウンタを、二人のユーザが同時に操作する場合がある。ユーザA、ユーザBがおり、お互いがカウンタの値を1ずつ増やす処理の時、Aが足して、更新をする前に、Bがカウンタを扱ってしまうと、値が変わらないままになってしまう。つまり、必ず、更新を行ったあとにお互いがカウンタに干渉するべきである。工夫として、待ち時間を置くという方法がある。
作成するプログラム
実際に時間をおいて処理をするというプログラムを書いてみた。
まず、変数iに変数countを代入する。次に、try文の中で、sleepメソッドで3秒間、時間を空けて、変数countに1 増やす。
一つ、気になるのが、なぜ、「count」と「i」で値を分けているのかという点だろうが、これは、グローバル変数か、クラス変数かの違いである。クラス変数はスレッド間で共有されるが、グローバル変数は、スレッドごとに用意される。なので、ローカル変数だけ操作するときは、同時操作の問題を考えなくてよい。
ブラウザでの結果を見てみる。
一度目は、「1」と表示されており、更新すると、数が増えていることが確認できる。
おわりに
今回は、マルチスレッドについてとても簡単に解説した。他にも、マルチスレッドを扱う際には、「synchronizedブロック」という方法もある。
次回は、HTTPのリクエストについて、解説していきたいと思う。
Servlet/JSP 基礎編11 フィルタ
フィルタとは
サーブレット・JSPを実行する前後に指定した処理を実行するための機能のことである。これをうまく使うと、共通処理を記述することで、全体のコード量を減らすことができる。
具体的に共通の処理というのは、レスポンスに対する文字エンコーディングやMIMEタイプ設定、逆にリクエストの文字エンコーディングなどがある。
フィルタを作成するために
フィルタを作成するためには、Filterインタフェースを実装したクラスを宣言しなければならない。まず、Filterインターフェースには、3つのメソッドが提供されており、必ず、オーバーライドしなければならない。
その3つのメソッドというのは、「doFilter」「init」「destroy」である。doFilterメソッドは、フィルタ適用時に呼び出される。initメソッドは開始時に一度、destroyメソッドは終了時に一度呼び出される。文字で書いても、理解が追い付かないと思うので、プログラムの中で詳しく書いていこうとおもう。
プログラムを作成する前に、最後、このフィルタの適用範囲を設定する。これは、Webアノテーションのように記述すればよい。正しくは、WebFilterアノテーションである。
プログラムの作成
実際のフィルタ部分のプログラムは以下である。
まず、1行目がWebFilterアノテーションである。URLパターンに「/*」と指定しているので、これから先の作成するサーブレット・JSP、すべてにこのフィルタが適用されることになる。
次に、doFilterメソッドを見てほしい。引数の中に、request,responseと、chainというものがある。これは、FilterChainインタフェースのインスタンスである。このchainを用いて、フィルタの終了時に行う後処理を記述することができる。
このメソッドの中では、リクエストとレスポンスのエンコーディングなどを設定している。そして、「chain.doFilter(request,response)」と書かれている。一見、引数の数が少ないと思うだろうが、これは、FilterChainインタフェースのdoFilterメソッドであり、先ほどのものとは別物である。これを書くことで、フィルタの後ろ側にある、サーブレット・JSPにリクエスト、レスポンス内容を送ることができる。逆に言うと、この処理がなければ、フィルタでリクエストが遮断されてしまう。
分かりにくいと思うので、図で表す。
最もシンプルに表すと上図のようになる。これで、「フィルタの後ろ側にあるサーブレット・JSP」や「フィルタでリクエストが遮断されてしまう」という意味が理解できると思う。
続きを解説する。initメソッド、destroyメソッドは、特に何も目的がないので、宣言だけをする。
あとは、適当なサーブレットを用意する。サーブレットのプログラムは以下である。
シンプルに「サーブレットの処理」と画面にでるようにした。
結果は以下である。
フィルタの前処理
サーブレットの処理
フィルタの後処理
まず、フィルタのプログラムで前処理が行われており、サーブレットの処理、戻ってきて、後処理が行われていることが分かる。今までのプログラムなら、文字化けが起きるはずだが、フィルタを通すことで、文字化けを防げている。
今後は、エンコーディングのことを気にせず、プログラムを書くことができる。
おわりに
今回は「フィルタ」について簡単に紹介してきた。以上で、「サーブレット・JSP 基礎編」は終わりである。次回からは「応用編」として、サーブレット・JSPだけでなく、データベースなど、本格的にWEBアプリケーションに使われている機能に触れていきたいと思う。
Servlet/JSP 基礎編10 リダイレクト
リダイレクトとは
リダイレクトとは、サーブレット・JSPがレスポンスで、指定したWebページをブラウザに開かせる機能のことである。実際にリダイレクトを経験した人も多いと思う。ブラウザで見てみると、サーブレットやJSPのファイルを開いたにもかかわらず、突然、別のURLを開いたかのようになる。
この機は、Webサイトが引っ越ししたときなどに利用されている。
メリットとデメリット
前回と今回で、「フォワード」「インクルード」「リダイレクト」という機能がでてきたが、それぞれの動きが理解できたでしょうか。少し難しいと思うので、図で表したいと思う。
まずは、フォワードの図である。
フォワードはリクエスト先のファイルから他のファイルに処理を完全に委託するイメージである。
次は、インクルードの図である。
インクルードは、処理を途中まで、他のファイルに委託し、返答をしてもらう。そして、残りのレスポンスまでを元のファイルで行う。
そして、次の図はリダイレクトである。
リダイレクトは、一旦、URLをレスポンスとして、ブラウザに返し、ブラウザは再び、そのURLへリクエストを送り、レスポンスを待つ。
これらの図を見れば、メリットとデメリットが理解できると思う。
まず、デメリットは、通信の回数である。「リダイレクト」はブラウザとサーバの通信が2往復で、他の二つは1往復である。
メリットは、外部のリソースにアクセスできることである。「フォワード」「インクルード」は内部リソースのみに限られる。
つまり、使いたいファイルが内部にあるのか、外部にあるのかで使い分けるべきである。
作成するプログラム
今回は、リダイレクトという機能を感じてほしいので、外部リソースのサイトを表示できるプログラムにする。そこで、作成したサーブレットを開くと、Tomcatのページを表示するようにする。
リダイレクトをするには、「sendRedirect」を利用する。引数には、URLを入れる。プログラムは以下である。
特に難しいことは書いていない。ただ、「sendRedirect」を使っていて、URLにTomcatのページを入力しているだけである。
実際に、このサーブレットを開くと、このような画面が出てきた。
これはTomcatのページである。しっかりとリダイレクトされていることがわかる。
さいごに
リダイレクトについて、解説した。これで、3つの画面遷移について、それぞれの違いやメリット、デメリットが理解して頂けたかと思う。次回は、「フィルタ」を紹介したいとおもう。フィルタを利用すると、複数のファイルを扱うときに、コード量を減らせるという利点があるので、是非、知っていただきたい。
Servlet/JSP 基礎編09 フォワード・インクルード
はじめに
この記事では「フォワードとインクルード」、次回は「リダイレクト」の二つについて解説します。なぜ、この二つを記事にするのかというと、実際のWebアプリケーションでは、サーブレットが使いやすいところ、JSPが使いやすいところで処理を回すのが普通であるからだ。そして、この処理を渡すのがフォワードやインクルードという技術である。
フォワードとインクルード
フォワードもインクルードも、他のJSP、サーブレットに処理を渡すという機能であるが、この二つの違いが気になる人もいるのではないだろうか?
二つの大きな違いは、フォワードは完全に処理を最後まで他のJSP、サーブレットに任せ、インクルードは、処理を任せる点は同じだが、最後の出力の処理を元の方でしなければならない。簡単に言うと、インクルードする側がレスポンスを出力するということである。
大して利点ではないと思えるが、複数のJSP、サーブレットで処理するとき、複数から出力するよりも、最後に一つの場所から出力できるほうが制御できる。
「フォワード」のプログラム
サーブレットからJSPへフォワードするプログラムを作成する。
今までの記事では、二つは別々で紹介していたが、これからは二つ同時に使っていきたいと思う。一つ目はサーブレットからJSPへフォワードをするので、ブラウザでサーブレットを開いたときに、JSP内の処理が画面に出れば、フォワード成功となる。
実際のサーブレットのプログラムは下記である。
これはサーブレットのプログラムである。「getRequestDispatcher」の引数には、サーブレット、JSPファイルのパスを入れる。これで、「forward.jsp」へ遷移するオブジェクトを取得できた。そして、「forword」で、フォワードを送ることができる。
ここから先は、JSPの処理に移る。JSPプログラムは下記である。
今回は、フォワードを確かめるだけなので、ブラウザに「フォワード先のJSPファイルです」という文を表示します。
実行した結果は以下のようになった。
サーブレットで開いたのだが、ちゃんとフォワードされて、JSPファイルの内容が表示されている。
「インクルード」のプログラム
次は、インクルードがどのようなプログラムで動くのか見てみたいと思う。
しかし、プログラムだけ見ても、あまりフォワードとの違いが分からないと思うので、雰囲気だけ味わっていただければと思う。
今回のプログラムでは、二つのJSPファイルにインクルードをし、その返答を呼び出し元のサーブレットで受け取り、画面に表示するというものにする。
まず、サーブレットは以下である。
フォワードの時と、同じく、「getRequestDispatcher」を使い、インクルード先のファイルを指定する。そして、「include」でインクルードを行う。
インクルード先のファイルのプログラムは次のとおりである。
これはinclude1.jspである。
これはinclude2.jspである。
いつもは、ヘッダーと、フッターのファイルをincludeディレクティブで入れているのだが、出力をサーブレット側で行うので、JSPファイルにそれらのファイルを入れる必要はなく、出力したいものを書き込むだけでよい。
結果は下記の通りである。
include1.jspの内容
include1.jspから戻ってきました
include2.jspの内容
include2.jspから戻ってきました
JSPファイルの処理をしてから、サーブレットのファイルへ戻ってきていることが分かると思う。
ちなみに、「フォワード」のサーブレットに次のようなプログラムを書き加えた。
先ほどと違うのは、printlnメソッドを加えた部分だ。
実行結果は、はじめと変わらなかった。
これで、「フォワード」と「インクルード」の違いがより理解できたと思う。
おわりに
今回は、画面遷移の「フォワード」と「インクルード」を紹介した。次回は「リダイレクト」について紹介する。「リダイレクト」と聞いたことがない人もいると思うが、経験した人はかなりいると思う。次回、お楽しみに!
Servlet/JSP 基礎編08 JSPのリクエスト処理
作成するプログラム
この記事では、JSPからリクエストパラメータを取得して、利用する方法を解説したいと思う。
そして、それを理解するための例として、テキストボックスに入力した内容をリクエストパラメータとして、処理し、画面に表示するプログラムと、入力内容を変数として扱い、計算結果を画面に表示するプログラムを作成する。
プログラム1
テキストボックスに入力した内容をリクエストパラメータとして処理し、画面に表示するプログラムを作成するために、まず、入力用のJSPファイル、出力用のJSPファイルを作成する。
入力用のJSPファイルを作成する。下記がそのプログラムである。
<p>タグで「お名前を入力してください」と表示し、下にテキストボックスを設置する。テキストボックスの横に、確定ボタンを設置し、押すと、リクエストが送られる。
送られたリクエストはformタグに書かれている、「greeting-out.jsp」が処理をする。
リクエストを処理する「greeting-out.jsp」を作成する。下記がそのプログラムである。
まず、リクエストとレスポンスとの文字エンコーディングを正し、<p>タグの中に、文字と、スクリプトレットの中で「getParameterメソッド」を利用する。
スクリプトレットさえ使えば、サーブレットと方法は全く同じである。
実際のブラウザでの画面は以下となる。
リクエストに対し、返ってきたレスポンスは以下である。
こんにちは、あああさん!
「こんにちは、〇〇さん!」と表示されていることが分かる。
プログラム2
次は、入力内容を変数として扱い、計算結果を画面に表示するプログラムを作成する。
このプログラムでは、テキストボックスを3つ使用する。
〇〇円 × 〇〇個 + 送料〇〇円=
のような感じで入力欄を設置し、このリクエストを送れば、計算し、結果を返すプログラムを作成する。
まず、入力欄のJSPページは以下である。
formタグで「total-out.jsp」を指定する。リクエストはこのファイルで処理される。
inputタグを3つ用意し、単品の金額、個数、送料を入力してもらい、最後に計算ボタンを押すと、リクエストが送られる。
ここで一つ、注意点があり、この3つの欄に数値以外のものが入力されると、エラーが出てしまうので、このエラーを想定したページも用意しなければなりません。
エラーページを作成するには、「isErrorPage属性」が必要となる。これを利用すると、例外処理を記述することができる。
実際のプログラムが以下である。
まず、ページディレクティブの中で「isErrorPage属性」をtrueにする。これで、例外処理の暗黙オブジェクトが利用できる。
使い方としてはスクリプトレットの中に式の形式で「exception」と書くだけでエラー内容が表示されるようになる。このページはこれで終わりである。
さいごに、最も重要な、「total-out.jsp」を作成する。
ページディレクティブに「errorPage」と書かれているが、これはエラーページの設定であり、エラーが発生した場合に表示されるファイルを書く。「total-error.jsp」は一つ上の例外処理を記述しているページである。
次に、スクリプトレットの中で「getParameterメソッド」で、リクエストパラメータを受け取り、「price*count+souryou」で計算をし、表示している。
結果は以下である。
計算結果は次のようになった。
100円×100個+送料100=10100円
10100円となっており、「100 * 100 + 100」がしっかりと計算されていることが分かる。
ちなみに、入力欄で数字以外のものを入力したときに返ってきたものも載せておく。
数値を入力してください
java.lang.NumberFormatException: For input string: "aaa"
「exception」と書くだけで、エラー内容が表示されていることが分かる。
さいごに
Servlet/JSP 基礎編07 JSP基本編
JSPとは
JSPについては、最も初めのServlet/JSP 基礎編01でも話しましたが、JSPファイルとは、HTMLの中にJavaプログラムを記述したものである。
実行のされ方は、ユーザがJSPファイルを開くと、アプリケーションサーバでJSPからサーブレットが生成され、コンパイル、最終的にはサーブレットプログラムとして実行される。つまり、最初の処理以外は、サーブレットと全く同じ処理ということである。
・メリット
JSPとサーブレットを比べてのメリットは大きく3点あると考えている。
1点目は、実行の容易さである。サーブレットの場合は、ソースのコンパイル、サーバの再起動が毎回必要になったが、JSPでは、ソースをエディタ上でセーブしておけば、ブラウザで確認できる。理由としては、アプリケーションサーバがJSPのコンパイルやその他の処理を自動で行ってくれるためである。
2点目は、修正の容易さである。これは1点目とほぼ同じ利点であるが、サーブレットは修正を加えると、再びコンパイル、サーバをリロードをしなければならない。しかし、JSPは、ブラウザの更新で修正をしてくれる。
3点目はHTMLの記述に適している。これは基礎編01でも話したことであるが、HTMLの出力が多いとき、Javaプログラムの中にHTMLを記述するサーブレットでは、毎回、printlnメソッドを使用しなければならない。逆にJSPでは、HTMLの中にJavaプログラムを記述する形であるから、HTMLを出力する場合は普段のHTMLファイルと同じような書き方でよい。それが利点である。
作成するプログラム
今回の記事では、シンプルに文字をブラウザに表示するプログラムと、変数を用いたプログラムの二つを作成したいと思う。
プログラム1
ブラウザの画面に「Hello」「こんにちは」と表示するプログラムを作成する。
<p>タグを使うだけでよい。
このプログラムでは、JSPの特徴を見ていただきたいと思う。
下記がそのプログラムである。
まず、何よりも気になるのが、1行目だろう。
これは、pageディレクティブという。JSPページに関する設定を行うことができる。
「contentType」でMIMEタイプと文字のエンコーディングを指定している。これにより、レスポンスをhtml形式で返すこと、文字化けを未然に防ぐことが可能となる。
次に、緑色のところが気になると思う。これは、見てもらった通り、コメント化である。「<%--」と「--%>」で囲めば、間の文字はコメントとなる。
あとは、<p>タグで表示したい文字を書けば終わりである。
ブラウザの結果が下記である。
Hello!
こんにちは
しっかりと表示されている。
プログラム2
二つ目のプログラムは変数を用いるものとする。しかし、ただのHTMLファイルでは、変数を扱うことはできないので、JavaプログラムをJSPファイルに書き込まなければならない。
Javaプログラムを記述するには、スクリプトレットという機能を使う。スクリプトレットは「<%」と「%>」で囲めばよい。
このプログラムでは、メソッドの宣言と変数の扱いを学んでいただきたい。
2行目では、「includeディレクティブ」を使用している。その名の通り、ファイルをインポートすることができる。このプログラムでは、header部分とfooter部分をインポートしている。これにより、プログラムをかなりシンプルにできる。
次に先ほど説明したスクリプトレットである。「!」がついているが、これは否定の意味ではなく、宣言の意味である。これを宣言することで、別のブラウザからアクセスしても、利用することができる。
次に、「<%=add(1,2) %>」の部分であるが、「=」を入れることで、式として扱われる。つまり、addメソッドの返り値がここに入る。
実行結果は以下の通りになった。
1+2=3
3+4=7
<p>タグで囲まれている部分で、返り値が当てはまっている状態で表示されていることが分かる。
おわりに
今回だけでは、スクリプトレットのことを完全に理解出ない人もいると思いますが、今後もスクリプトレットを利用したJSPを作成していくので、よろしくお願いいたします。
Servlet/JSP基礎編06 パラメータ名の取得
作成するプログラム
今回のプログラムでは、リクエストパラメータの名前を取得する方法を解説したいと思う。リクエストパラメータの名前とは、HTML文書の方でタグの中に書かれている、name属性の名前のことである。この名前を取得し、画面上に、リクエストパラメータ名とそこに格納されている値を表示したいと思う。
HTMLの作成
HTMLは前回と似たような形のものにしたいと思う。セレクトボックスと、ラジオボタン、チェックボックスを利用する。
プログラムは下記の通りになる。
具体的なプログラムの内容は、レストランの予約のページである。
まず、セレクトボックスで、予約人数の選択、ラジオボックスで、座席の選択、チェックボックスでオプションの選択ができる。そして、予約のボタンを押せば、サーブレットにリクエストを送られる。
サーブレットの方では、このHTMLの「name属性」と、そこの値を取り出すことが目的である。
サーブレットの作成
作成するサーブレットは先ほど説明した通り、リクエストパラメータ名と、値を取り出すことが目的のプログラムを作成する。
まず、リクエストパラメータ名を取得するには、getParameterNamesメソッドを利用することで手に入れることができる。
しかし、このメソッドの戻り値はEnumerationオブジェクトである。なので、通常の変数には、格納することができない。そこで、Collectionクラスのlistメソッドを使い、ArrayListに変換をし、繰り返し処理で表示することにする。
下記はサーブレットプログラムである。
リクエスト引数やレスポンス変数を使う前には、文字エンコーディングをしないといけないので、「setContentType」「setCharacterEncoding」を使用する。
そして、ArrayList配列のnamesにlistメソッドを利用して、リクエストパラメータ名を全て格納する。
繰り返し処理の中では、「getParameterValues」を使う。これは、「getParameter」が一つの値を取り出すのに対し、「getParameterValues」は複数の値を取り出すことができる。
配列valuesに値をいれ、もう一つの繰り返し処理で、
「リクエストパラメータ名 = リクエストパラメータ」のように表示する。
ブラウザの画面は以下のようになる。
人数は2で、座席は喫煙、オプションはケーキと花束で選択した。
サーブレットから返信された画面は以下である。
count=2
seat=喫煙
option=ケーキ
option=花束
「count」「seat」「option」はパラメータ名である。countやseatは値が一つしかないので、一つのみ表示されるが、「option」は0~2個の選択が可能であるから、複数であるときは、「getParameterValues」で複数取り出されていることがわかる。
おわりに
今回はデバッグの際に必要となるリクエストパラメータ名の取り出し方を解説した。これを利用すれば、どのタグがどのような値を取っているのかわかる。