####● Web アプリケーションの設計を考える前に、基礎となるオブジェクト指向設計、インターネット通信の仕組みについて記述する
###■ オブジェクト指向設計の基本について
オブジェクト指向設計とは…
全てをモノとして捉えて設計するための考え方、設計した内容を正しくプログラムに落とし込むことができるのがオブジェクト指向言語の特徴
1つの役割を明確にして持たせることで情報が共通化され、拡張性や再利用性が高まり使いやすくなる、大規模プロジェクトに向いている理由もここにある
######■ オブジェクト指向設計の原則
オブジェクト指向設計において守るべき5つの原則「 SOLID の原則」がある
1.SRP:単一責任の原則
2.OCP:オープン / クローズドの原則
3.LSP:リスコフの置換原則
4.ISP:インターフェース分離の原則
5.DIP:依存性逆転の原則
1.単一責任の原則
SOLID の原則の根幹となる原則、この原則を順守することで残り4原則についても自然と設計することができる
クラスは1つのことだけに責任を負うこと、つまり1クラスに1つの役割だけを持たせるということ
設計中、プログラミング中に、このクラスは役割を複数持っているのでは、と感じたら設計を見直すべきで、余計なフィールドやメソッドなども含めるべきでない
2.オープン / クローズドの原則
提供されている機能の拡張は可能(オープン)で、修正に対しては影響を受けない(クローズド)であること
ポリモーフィズムでは、例えばスーパークラスやそのサブクラスが将来的にどのような拡張や修正のされ方(メソッド内容の変更など)をしたとしても、使う側は修正の必要などの影響を受けない、ということ
3.リスコフの置換原則
スーパークラスで実装可能なものは、サブクラスに置き換わっても動作可能であること
4.インターフェース分離の原則
インターフェースはクライアントが望まないメソッドを強要してはならない
インターフェースで定義されているものは、実装するクラスですべて実装しなければならず、その中に適切でないメソッドが含まれていた場合設計が破綻してしまう可能性がある( Human クラスに空を飛ぶメソッドがある、のようなイメージ)
5.依存性逆転の原則
スーパークラスはサブクラスに依存してはならない(スーパークラスの中でサブクラスのオブジェクトを呼んでいる)
どの原則も土台には「役割を明確にするべき」という考え方がある
###■ インターネット通信の仕組みについて
####■ コンピュータの構成について
コンピュータは以下
・アプリケーション
・ミドルウェア
・OS
・ハードウェア
主に上記4つで構成されている
ミドルウェアとは処理を行うアプリケーションと、制御をするOSとの間に存在するソフトウェアのこと
ミドルウェアには以下3つのサーバーがある
######① Webサーバー(Web)
クライアントからのリクエストに対して「静的コンテンツを見せること」、「APサーバに動的コンテンツを要求し、返ってきた結果を見せること」という2つの役割を担う
(静的コンテンツは常に同じ内容を表示するもの、動的コンテンツはネットバンキングの残高やネットショッピングのカートなど)
どちらもブラウザからのリクエストに応じて表示を変化させ、動的なWebコンテンツへのリクエストだった場合にアプリケーションサーバーへリクエストを転送する
Webサーバを操作する代表的なソフトウェアは「Apache(アパッチ)」
####👇処理要求 👆処理結果
######② アプリケーションサーバー(AP)
ここが処理の中核 Webサーバから受けたリクエストをもとにJavaやRuby、PHPなどで作成されたアプリケーションを実行して動的コンテンツを生成する
必要であればDBサーバへリクエストを行い、返ってきたデータを加工して動的コンテンツに埋め込む
“必要であれば”というのは、例えば「1+1は?」というリクエストに対して、四則演算のアプリケーションが実装されているAPサーバであれば、わざわざDBサーバに問い合わせてデータを持ってくる必要はないが、「リンゴとバナナの合計金額は?」というリクエストの場合は、APサーバにはリンゴとバナナの値段のデータが存在しないためDBサーバにリクエストし、帰ってきた値段を元にAPサーバ上で計算して、結果をWebサーバに返す
代表的なものは「Tomcat」や「Glass Fish」など
⇒Tomcatはアプリケーションサーバであるが、簡易的なWebサーバ機能も備えている
####👇データ要求 👆要求されたデータ
######③ データベースサーバー(DB)
データベース管理システムが動作しているサーバのこと
大量なデータの保管は「ストレージ」の役割で、DBサーバはストレージに新たなデータを書き込んだり、必要な情報を引き出したり更新したりする
APサーバのリクエストに従って「SQL」というデータベース言語を実行し、その結果をAPサーバに返す
代表的なものは Orcle の OlacleSQL や MySQL、MicroSoft の SQLServer など
以上のクライアントからのリクエストに対する処理のことを「 Web3 層構造」と呼ぶ
Web3 層構造が採用される理由の 1 つに「セキュリティの高さ」があげられる
DBサーバには多くの顧客情報が保存されており、Web、AP、DB がすべて 1 台にインストールされたシステムではクライアントから直接 DB サーバにアクセスできてしまうが、Web3 層構造ではクライアントと DB サーバの間に Web サーバ、AP サーバ、そしてセキュリティ製品を配置できるためより堅牢になる
また、「管理がしやすい」点も大きな理由
システムは『止まってもすぐに復旧できる』ことを前提に作られるため、サーバに不具合が発生した場合も、Web 機能がおかしいのであれば Web サーバの故障、アプリケーションエラーが出ているのなら AP サーバの故障と、1 台に機能が集約されている場合と比較して故障の影響が軽微になる
システム全体としても全停止ではなく一部機能の停止で済み、また例えば AP サーバの拡張が必要な場合にも AP サーバのみと柔軟に対応することが可能
####■ HTTP 通信
ブラウザと Web サーバ間の通信でどのようなデータをやり取りするかは、HTTP というルール(プロトコル)によって決められており、ブラウザが Web サーバに対して出すリクエストのことを「 HTTP リクエスト」、対して Web サーバがブラウザの HTTP リクエストに返すレスポンスを HTTP レスポンスという
1度の HTTP リクエストに対しては、1つのレスポンスが必ず返ってくるという「1リクエスト・1レスポンス」が基本
######■ HTTP リクエスト
リクエストには各種メソッド(リクエストメソッド)があり、使用頻度の高いものの例として
1.GET:サーバの情報を取得する処理をリクエスト
2.POST:サーバの情報を送信する処理をリクエスト
3.PUT:サーバの情報を更新する処理をリクエスト
4.DELETE:サーバの情報を削除する処理
同じリクエストでも用途に応じてリクエストの種類を使い分けるのが作法となっている
実際のリクエストの例として
GET /index.html HTTP1.1
リクエスト、レスポンスの内容はヘッダ部とボディ部に分かれている(HTMLと同じイメージ)
冒頭の「 GET 」メソッドでどのリクエストかが指定され、URLのパス、HTTPのバージョンと続く
######■ HTTP レスポンス
HTTP/1.1 200 OK
.....
Content-Type: text/html; charset=UTF-8
<html>
.....
</html>
こちらは HTTP のバージョンが冒頭にきて、次にステータスコード(200)がくる
URLのリンク切れの際に 404 NOT FOUND と見かける 404 も同じステータスコードで、補足メッセージの「 NOT FOUND 」、そのまま「リクエストされた対象が見つからない」がついている
そのほか、以下
・405:リクエスト対象が、使用したリクエストメソッドを許可していない
・500:サーバー内部でエラーが発生した
Content-Type:..... はContent-Type ヘッダといい、ヘッダ以下からボディ部になるが、そのボディ部が何のデータであるかを示している(上記であれば HTML で文字コードがUTF-8と明示) JPEGの画像ファイルであれば Content-Type:image/jpeg; など
ブラウザに「○○のデータですよ」と教えてあげなければ、ブラウザは正しく以下ボディ部のデータを読み取れない
これまでの基礎情報を合わせて考えると
・Web ブラウザ ⇒ Web サーバ:HTTP リクエストの送信
・Web サーバ ⇒ AP サーバ:AP サーバへリクエスト内容の処理の要求
・AP サーバ ⇔ DB サーバ:DB サーバからデータを取得
・AP サーバ ⇒ Web サーバ:AP サーバから受け取った結果を Web サーバへ転送
・Web サーバ ⇒ Web ブラウザ:HTTP レスポンスの送信
という流れ
後述する MVC パターンを取り入れた Web アプリケーションを作成するために、今回のサーブレット・JSP が AP サーバの役割としてサーバ上で動作する、Java EE で提供されている機能である
以上のような仕組みを利用し、Web サーバで公開しブラウザで実行できるようにしたアプリケーションを Web アプリケーションという
###■ サーブレット
サーブレットは Java を用いてサーバーサイドプログラムを作成するための機能
サーブレットクラスというクラスを作成することで、AP サーバー上でそれらを実行することができるようになる
このサーブレットクラスはブラウザからの動的な Web コンテンツへのリクエストをうけた Web サーバーから転送され実行し、その実行結果を HTML で出力する
サーブレットクラスを作成する際には、デフォルトで以下のコードが記載されている(一部省略して記載)
【 Sample サーブレット】
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/SampleServlet")
public class SampleServlet extends HttpServlet {
protected void doGet(
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().append("Hello");
}
protected void doPost(
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
まず作成したサーブレットクラスは基本として HttpServlet という元となるクラスを継承し必要な機能を備えており、その中で、Java の main メソッドのようなイメージの doGet メソッドをオーバーライドし、実行内容をメソッド内に記述する
(正確には main メソッドはサーブレットクラス内ではなく、Tomcat の中に存在し、main メソッドの中でサーブレットクラスの椅子タンスが生成、 doGet メソッドや doPost メソッドが呼び出される、という仕組み プログラムの実行内容をメソッド内に記述するという点で Java プロジェクトの main メソッドのイメージと捉えている)
Web サーバーからリクエストが送られてくると、AP サーバー( Tomcat )はまず doGet メソッドを呼び出し、引数としてブラウザから届いたリクエスト(HttpServletRequestへ)、サーバーから送り出すレスポンスに関する情報と機能(HttpServletResponseへ)を引数として渡す
サーブレットクラスでは基本的に
1.HttpServletRequest クラスのインスタンスに格納されているリクエストの詳細情報を取り出し、計算等様々な処理を行い
2.HttpServletResponse クラスのインスタンスを用いて結果画面の HTML 情報をブラウザに送信する
####★ Web アプリケーションの処理のほとんどはこの2つのインスタンスを用いて実現されている
サーブレットクラスのメソッドの種類は、HTTPリクエストがどのメソッドでリクエストしてきたかに応じる
・GETリクエスト ⇒ doGetメソッド
・POST ⇒ doPostメソッド
・PUT ⇒ doPutメソッド
・DELETE ⇒ doDeleteメソッド
またどのリクエストメソッドになるかは、どのようなブラウザの操作でリクエストを行ったかによって決定する、例えば
GET リクエストが送信されるのは
・アドレスバーに URL を入力したとき
・リンクをクリックしたとき
・ブックマークを選択したとき
・method 属性が get のフォームの送信ボタンをクリックしたとき など
POST リクエストが送信されるのは
・method 属性が post のフォームの送信ボタンをクリックしたとき など
HTTPの世界では原則「GETリクエスト」が使われるため、明示的にPOSTリクエストを使用しない限りはGETで処理される
ただしGETリクエストはURLに情報が載ってしまうため、検索などの場合はリクエストパラメータ(URLの末尾)に乗っても問題ないが、例えばログイン情報などをクライアントからサーバに送る際などは、POSTでリクエストを送るように開発側で設計する必要がある(詳細に言えばPOSTでもリクエストパラメータに乗らないだけで、リクエストのボディ部には情報がそのまま格納されている、「暗号化」したうえでPOSTするということになる、そしてこの「暗号化」されたURLがHTTPS「Secure」プロトコルである)
というような使い分けがある
上記のコードで実行の内容部分は
response.getWriter().append("Hello");
の箇所で、 getWriter メソッドで文字を出力している
デフォルトのコードは以上のような内容
####■ 実行方法について
サーブレットクラスを実行するには、ブラウザでサーブレットクラスの URL を指定してリクエストする 形式は以下
http:// <サーバー名> / <アプリケーション名> / <URLパターン>
この URL パターンについては、そのクラスをリクエストするときの呼び名のようなもので、サーブレットクラスは URL パターンを設定しなければリクエストして実行することはできない
######・ サーバー名、アプリケーション名
ホストとポート番号に分かれており、自分の PC であればホストは localhost で、ポート番号は http であれば 80 、 https であれば 443 と決まっており、また Tomcat はデフォルトで 8080 番のポート番号で動作するようになっている
アプリケーション名は正確にはコンテキスト・パスと呼ばれ、そのまま = Eclipse のプロジェクトの名前となる
######・ URL パターン
上記のデフォルト設定のコードで
######@WebServlet("/SampleServlet")
というアノテーションがあったが、この@WebServlet アノテーションで URL パターンを設定しており、デフォルトではクラス名と同じで設定される( URL パターンは / から始まる)/hello とかに変えてもよい
サーブレットクラスの新規作成の際に URL マッピングの欄に記述することで設定できる
リクエストして サーブレットから返ってきた HTML のリンクからまた別のサーブレットにリクエストして...というのが通常の Web アプリケーションの流れ
######・リクエストパラメータ
URL の末尾の「 ? 」以降に名前(キー)+値で持たせる
リクエストパラメータは「HttpServletRequest インスタンス」に格納され、リクエスト先のサーブレットや JSP に渡される
サーブレットや JSP では HttpServletRequest のメソッドを使用してリクエストパラメータを取り出すことができる
###■ JSP ( Java Server Page )
Java (サーブレット)の中に HTML を書くのではなく、 HTML の中に Java を書くという方法
中身の表示する内容は枠として存在し、ブラウザからリクエストを受けたサーブレットが、リクエストの内容に応じて適宜内容を変えるという仕組み
例えば EC サイトの検索画面では、利用者が検索ワードを入力(リクエスト)すると、それ応じて(サーブレットによって)絞り込まれた画面( JSP )が表示される、というイメージ(実際に実行するのは main メソッドがある Tomcat で、 Tomcat が JSP をサーブレットに変換して実行するという仕組み)
HTML は今では JavaScript などで動的に書き換えることができるが、単体ではリクエストは遅れてもレスポンスを受け取ることできないため、サーバーから受け取った情報を加工したり、動的に表示させることができず、文字や画像などの静的コンテンツの表示を主な役割としている、JSP は元々この部分を補足する機能として活用されていた
MVC の View として切り離して作成、Controller であるサーブレットから情報を受け取って、自由に加工したり動的に表示させる(動的コンテンツの表示)
JPS要素( <% )を HTML内に埋め込むことで、そのJSPページの設定や、Javaのコードをそのまま記述できる(Javaのコードは条件分岐うや繰り返しなど、あくまで補助的な使用にとどめる)
JSP の記述は以下、簡単な条件分岐のコードを例に
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
int jap = 30;
int eng = 50;
int total = jap + eng;
%>
<p> total = <%=total%></p>
<%-- 条件分岐 --%>
<%if (total >= 70) {%>
<p>合格点</p>
<%} else {%>
<p>赤点</p>
<% } %>
</body>
</html>
【基本的な記述方法】
・スクリプトレット:HTML に Java を埋め込むための <%>
・スクリプト式:<%=> の記述、変数や演算式、メソッドの戻り値などを記述できる
・JSP コメント:<%-- --%> でコメントが記述できる
・ page ディレクティブ:<%@ page 属性名⁼値 %> でその JSP ファイルに関する様々な設定を行うことができる
⇒冒頭の language="java" contentType="text/html; charset=UTF-8" がこれにあたり、import する際にもこれを使用する
###■ MVC パターンについて
Model : データを扱う部分
View : 表示を行う部分
Controller : リクエストを処理して結果を返す部分
以上 3 つの役割で分ける設計パターンを MVC パターンという
プロジェクトで複数の機能を別々に実装したり、複数人で共同作業したりする際に用いられ、保守作業も容易になるという特徴があり、Web アプリケーション作成における一般的な設計パターンとなっている
今回のサーブレット、JSP では、サーブレットが Controller、JSP が View の役割をそれぞれ担う
それぞれの項目での述べたように、サーブレットでも HTML の記述が、JSP でもスクリプトレットによる Java の命令文の記述が可能であるが、MVC の役割に基づくならば
######サーブレットで一連の処理を行う ⇒ View となるJSP を最後に呼び出す
という動きを考えるべき
また、Model については、クライアントからの要求(検索など)に応える処理や、その処理に関係するデータ(検索結果など)を表すモデルで、一般的な Java のクラスがその役割を担う
(JDBC)
###■ サーブレットから JSP を呼び出す
前項のサーブレットで一連の処理を行い、その後 JSP を呼び出すのには、「 getRequestDispatcher メソッド」を使用する
pritected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
RequestDispatcer rd = request.getRequestDispatcher("/WEB-INF/sample.jsp");
rd.forward(request, response);
}
JPS の呼び出しにはこのメソッドを使用するため、おまじないのようなコードでもあるが、内容としては以下
######■ getRequestDispatcher
次の画面に進むための準備として getRequestDispatcher メソッドが、定義されている HttpServletRequest クラスの変数 request ( HttpServletRequest request )から getRequestDispatcher を呼びだす( request.getRequestDispatcher() )
この時点では画面の表示(レスポンス)ではなく、あくまで処理(リクエスト)の転送のため request となっている
そして引数として次の画面の名前("/WEB-INF/Sample.jsp")を指定する
その後、getRequestDispatcher のオブジェクトを変数 rd に格納し、そのオブジェクトから forawrd メソッドを呼び出し、レスポンスの画面として JSP ファイルを呼び出す
引数に(request, response)を渡しているが、渡す理由は、転送先でも request と response の変数の中身が使いまわせるように渡している
######■ forward / redirect
上記の forward メソッドは処理を指示するための方法の1つで、主にサーブレットからサーブレットへ処理を転送するという指示を行う、JSP ファイルへあとはお願い、とするときの処理の橋渡し役
基本的に JSP ファイルは MVC パターンに従って作成する以上、ブラウザから直接アクセスすることはなく、そのことを前提にファイルも作成するため、仮に直接アクセスされたとしても不具合やエラーが発生することがあるため、直接アクセスできないディレクトリ以下に配置する( Eclipse であれば WEB - INF 内に JSP フォルダを作成し格納する)
もう一つ、redirect は他のサーバーなど、まったく別のところにリクエストを自動的に送信する指示をブラウザに行い、ブラウザはそれに従い指定された先へ自動的にリクエストを行う、処理の譲渡役
redirect は他の場所へ再度リクエストしてください、というレスポンスのためresponse メソッドで、 sendRedirect メソッドを使用する
引数にはリダイレクト先の URL を指定
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect("/Sample/SampleServlet2");
上記の /Sample でアプリケーション名を指定し、/SampleServlet2 でサーブレットを指定して転送するという流れ
フォワードもリダイレクトも役割としては似ているが、大まかな使い分けとして、
・転送元と転送先のアプリケーションが異なる場合、リダイレクトを使う必要がある
・転送元と転送先のアプリケーションが同じ場合、フォワードはリクエスト&レスポンスが1回(1往復)であるのに対し、リダイレクトは2回(2往復)であるため、転送が1回分早く済むフォワードを使用するほうがベター
・フォワードは転送後もアドレスバーにリクエスト時の URL が表示されるのに対し、リダイレクトはリダイレクト先の URL に変更されるため、URL と表示画面のズレによって不具合が生じる可能性があれば、アプリケーション内部での転送にもリダイレクトを使用する
という使い分け
######■ getParameter / setAttribute
先述したリクエストパラメータを取得するのが getParameter
取得したデータを次の画面などに受け渡したいときに使用するのが setAttribute
######http://localhost:8080/Sample/SampleSrevlet?name=Tanaka&age=20
上記の URL にアクセスした場合、リクエスト先の SampleServlet では Tanaka というデータ(文字列)が格納された変数 name をパラメータとして受け取ることができる
このパラメータを受けとるときに使用するのが getParameter メソッド
リクエストパラメータは「HttpServletRequest インスタンス」に格納され、リクエスト先のサーブレットや JSP に渡される
サーブレットや JSP では HttpServletRequest のメソッド、getParameter , setAttribute メソッドをを使用してリクエストパラメータの取得、転送を行うことができる
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String age = request.getParameter("age");
request.setAttribute("name", name);
request.setAttribute("age", age);
RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/Sample.jsp");
rd.forward(request, response);
リクエストの処理なので、request のインスタンスからそれぞれ getParameter , setAttribute メソッドを呼び出し、上記の URL で設定されているリクエストパラメータの変数 name , age を文字列で引数に指定し受け取る
getParameter メソッドで取得した値はすべて String 型のデータとなり、値を数値として扱いたい場合には一旦 String 型のデータとして受け取った後に数値への変換処理が必要( Integer.parseInt メソッドを使用、上記では String 型のデータのまま扱う)
setAttribute では、第一引数に「変数名」、第二引数に「値」を記述し、取得したパラメータを転送する処理を行う
その下は先述した getRequestDispatcher メソッドで次の画面を指定して forward で転送指示を行っている
###■ スコープ
上記でサーブレットと JSP の連携方法については記述したが、あるサーブレットで生成したインスタンスを別のサーブレットや JSP で利用したいとき、フォワード元のサーブレットクラスでし生成したインスタンスの名前をフォワード先の JSP で指定しても利用できない( if 分の時の変数のスコープのイメージ、ブロック内で定義した変数をブロック外で使用できない)
※ちなみに request のインスタンスは JSP 内でも普通に使用できるが、これは「暗黙のオブジェクト」と呼ばれる宣言不要のオブジェクトの一つとして用意されている
ここで使用するのが「スコープ」というサーブレットや JSP をまたいでデータを共有できる保存領域
スコープに保存できるのはインスタンスに限られる、そのため int 型や double 型などの基本データ型変数はインスタンスではないため、スコープに保存できない
基本データ型を保存したい場合は、ラッパークラス( Integer や Double など)を使用する
ラッパークラスのインスタンスを保存する場合は、「 JavaBeans 」というクラスのインスタンスを保存する
保存するインスタンスの有効期限によって4つのスコープに種類が分かれる
・ページスコープ ・リクエストスコープ ・セッションスコープ ・アプリケーションスコープ######■ リクエストスコープ
「一つのリクエストに対するレスポンスの画面まで」が有効期限となるスコープ
先述した setAttribute (変数<属性名> , 値<インスタンス>)メソッドは取得したパラメータの転送記述したが、正確にはインスタンスをリクエストスコープに保存する処理を行っている
リクエストスコープに保存したインスタンスは JSP 側で取得するが、その処理は getAttribute メソッドで行う
getAttribute メソッドも request オブジェクトで定義されているため、先述した暗黙のオブジェクトによりそのまま使用することができる
先ほどのコードで
【サーブレットクラス : SampleServlet 】
public class SampleServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String age = request.getParameter("age");
request.setAttribute("name", name);
request.setAttribute("age", age);
RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/JSP/Sample.jsp");
rd.forward(request, response);
}
}
【 JSP ファイル: Sample.jsp 】
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>プロフィール</h1>
<p>名前:<%=request.getAttribute("name") %></p>
<p>年齢:<%=request.getAttribute("age") %>
</body>
</html>
上記のサーブレットと JSP で
######http://localhost:8080/Sample/SampleServlet?name=Tanaka&age=20
SampleServlet にブラウザからリクエストを出すと、name と age のパラメータを getParameter メソッドで受け取って setAttribute メソッドでインスタンスをセッションスコープに格納し、JSP ファイルにフォワードする
JSP ファイルでは getAttribute メソッドでインスタンスを取得し表示するという流れ
この1往復のリクエスト、レスポンスがリクエストスコープの有効期限となる
######■ セッションスコープ
「 Web アプリケーションを使用している間 <セッションが有効な間> 」が有効期限となるスコープ 意図的にスコープのデータを消去する、ブラウザを終了する、セッションの有効期限が切れる、のいずれかまでデータを利用することができる
サイトのログインに関連した処理に利用される(会員登録メニューは1ページ入力して次の画面をリクエスト、また入力して.....登録完了するまでブラウザが移っても入力したデータが保存されている)
以下 JSP ①~③を作成し、簡易的なログイン、ホーム画面、ログアウト画面の表示を行う
JSP 間でセッションスコープに保存したデータを共有する
【 Sample ① 】
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% request.getSession().setAttribute("name", "Tanaka"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログイン</title>
</head>
<body>
<h1>ログインしました。</h1>
<p><a href="Sample2.jsp">ページ②</a></p>
</body>
</html>
######<% request.getSession().setAttribute("name", "Tanaka"); %>
上記で セッションスコープに "Tanaka" という文字列が入った変数 name を保存、リンクの Sample2.jsp へ飛ぶ
【 Sample ② 】
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%String name =(String)request.getSession().getAttribute("name"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ホーム画面</title>
</head>
<body>
<h1>ホーム</h1>
<h2>ようこそ <%=name %> さん</h2>
<p><a href="Sample3.jsp">ページ③</a></p>
</body>
</html>
######<%String name =(String)request.getSession().getAttribute("name"); %>
セッションスコープに保存した変数 name を取り出し、この JSP ファイル用の変数 name にデータを格納する
このメソッドで取り出したデータは Object 型という汎用的な型になっているため、利用したいオブジェクトの型へキャストする必要がある(今回は "Tanaka" という文字列データのため String でキャスト)セッションスコープのデータの取り出し方として理解する
######<h2>ようこそ <%=name %> さん</h2>
ここで取得したデータを変数で記述できる
【 Sample ③ 】
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%request.getSession().removeAttribute("name"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログアウト</title>
</head>
<body>
<h1>ログアウトしました。</h1>
<p><a href="Sample.jsp">ページ①</a>
<p><a href="Sample2.jsp">ページ②</a></p>
</body>
</html>
######<%request.getSession().removeAttribute("name"); %>
上記のメソッドでセッションスコープに保存した name のデータを消去している
######http://localhost:8080/Sample/Sample.jsp
ブラウザで実行すると
ログイン ⇒ ホーム ⇒ ログアウト とリンク伝いに進めるが、③のログアウトの JSP 内の removeAttribute メソッドでスコープのデータを消去しているため、リンクで②のホームの JSP に戻っても「ようこそ Null さん」とデータが消えている
######■ アプリケーションスコープ
「Webアプリケーションが起動して終了するまでの間」が有効期限となるスコープ
セッションスコープはブラウザを閉じたら(セッションが終了したら)データが消えるのに対し、アプリケーションスコープはブラウザを終了しても、Tomcat を再起動しない限りデータが残り続ける
setAttribute は
request.getServletContext().setAttribute()
getAttribute は
request.getServletContext().getAttribute()
というように記述する