第 7 章.サーブレット 間 の 連 携 学 習 のねらい 1 Web アプリケーションの 処 理 を サーブレット JSP そして HTML ファイルによる 処 理 分 担 あるいは 連 携 によって 実 現 する 仕 組 みを フォワード(forward) インクルー ド(include)およびリダイレクト(redirect)の 活 用 方 法 を 通 じて 学 習 する 2 また リクエスト 属 性 のやりとりも 学 習 する < 先 週 の 復 習 > 講 義 で 示 された 基 礎 課 題 7-1 に 解 答 して 下 さい 7-1.フォワード(forward)による 処 理 の 受 け 渡 し 基 礎 課 題 6-6 では 男 女 の 性 別 を 選 択 すると それぞれの 専 用 ページを 表 示 するという Web アプリケーションを 作 成 しました そこでは 男 性 女 性 専 用 ページをサーブレット で 直 接 記 述 しましたが その 内 容 が 複 雑 になって 来 ると それぞれのページを 記 述 する( 専 用 の){サーブレット JSP HTML ファイルを 呼 び 出 して 表 示 させた 方 が 見 通 しが 良 くなります ここでは そのやり 方 を 学 習 しましょう 処 理 の 流 れをイメージとして 表 す と 次 のようになります forward 男 性 専 用 ページの 表 示 性 別 の 選 択 (JSP) リクエスト 表 示 の 振 り 分 け (サーブレット) (サーブレット JSP HTML 文 書 ) 女 性 専 用 ページの 表 示 forward (サーブレット JSP HTML 文 書 ) 以 下 の 手 順 にしたがって この Web アプリケーションを 作 成 しましょう 87
1 radiobutton.jsp を 次 のように 修 正 し radiobutton2.jsp と 別 名 保 管 してください 下 線 部 が 修 正 箇 所 です <%@page contenttype="text/html; charset=windows-31j"%> <HTML> <radiobutton2.jsp> <BODY> <H2>ラジオボタンからの 入 力 </H2> あなたは 男 性 ですか 女 性 ですか?<br> <FORM ACTION="../RadioButtonServlet2" METHOD="POST"> <INPUT TYPE="RADIO" NAME="Sex" VALUE="Dansei"> 男 性 <INPUT TYPE="RADIO" NAME="Sex" VALUE="Josei"> 女 性 <br> <INPUT TYPE="SUBMIT" VALUE=" 送 信 "> <INPUT TYPE="RESET"> </FORM> </BODY> </HTML> 2 次 に RadioButtonServlet.java を 次 のように 修 正 して RadioButtonServlet2.java と 別 名 保 管 してください import javax.servlet.requestdispatcher; <RadioButtonServlet2.java> 1RequestDispatcher クラスをインポート public class RadioButtonServlet2 extends HttpServlet { String Sex=request.getParameter("Sex"); RequestDispatcher dispatcher; 2 RequestDispatcher クラスのオ if(sex.equals("dansei")) { ブジェクトを dispatcher と 命 名 request.getrequestdispatcher("/danseiservlet"); else { 3 getrequestdispatcher メソッドの 引 数 には 処 理 を 割 り 当 てるサーブレットのパス 名 を 指 定 する request.getrequestdispatcher("/joseiservlet"); dispatcher.forward(request, response); 4 forward()メソッドにより 3で 指 定 したサーブレットへ 処 理 が 移 る 88
3 上 で 呼 び 出 される DanseiServlet.java を 次 の よ う に 作 成 し て く だ さ い RadioButtonServlet.java を 別 名 保 管 して 修 正 すると 便 利 です import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; <DanseiServlet.java> public class DanseiServlet extends HttpServlet { response.setcontenttype("text/html;charset=windows-31j"); PrintWriter out=response.getwriter(); out.println("<html>"); out.println("<head>"); out.println("<title> 男 性 専 用 ページ</TITLE>"); out.println("</head>"); out.println("<body>"); out.println("<h2> 男 性 専 用 ページ</H2>"); out.println("ようこそ 男 性 専 用 のページへ"); out.println("<body>"); out.println("</html>"); 4 上 の DanseiServlet.java を 別 名 保 管 して JoseiServlet.java を 作 成 してくださ い 変 更 点 は 次 の 通 りです クラス 名 を DanseiServlet JoseiServlet へ 変 更 男 性 専 用 の 表 示 部 分 を 女 性 専 用 へ 変 更 (3 箇 所 ) 5 最 後 に web.xml に 次 ページのように 追 加 してください < 補 足 > RequestDispatcher クラスの dispatch とは 派 遣 する という 意 味 の 単 語 です プロ グラミングでは( 処 理 を) 割 り 当 てるという 意 味 で 使 われます まさに 処 理 を 他 のサーブ レットや JSP に 割 り 当 てるために 用 意 されているのが このクラスです 89
<web.xml> <web-app> 追 加 部 分 のみを 記 述 <servlet> <servlet-name>radiobuttonservlet2</servlet-name> <servlet-class>input.radiobuttonservlet2</servlet-class> </servlet> <servlet> <servlet-name>danseiservlet</servlet-name> <servlet-class>input.danseiservlet</servlet-class> </servlet> <servlet> <servlet-name>joseiservlet</servlet-name> <servlet-class>input.joseiservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>radiobuttonservlet2</servlet-name> <url-pattern>/radiobuttonservlet2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>danseiservlet</servlet-name> <url-pattern>/danseiservlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>joseiservlet</servlet-name> <url-pattern>/joseiservlet</url-pattern> </servlet-mapping> </web-app> 基 礎 課 題 7-2 作 成 したら 動 作 を 確 認 してください radiobutton2.jsp に 接 続 し 例 えば 女 性 を 選 択 した 場 合 次 のように 表 示 されま す このとき URL に 注 目 してください 処 理 が 割 り 当 てられた /JoseiServlet ではなく /RadioButtonServlet2 の ままになっているはずです 処 理 を JoseiServlet に 割 り 当 てたのはサーバ 側 の 処 理 なので クライアント(ブラウザ)から 見 ると /RadioButtonServlet2 に 接 続 されたままに なっています この 点 を 確 認 したら 動 作 を 確 認 しました と 記 述 して 提 出 して 下 さい 90
処 理 を 転 送 する(forward する)のは サーブレットだけではなく JSP に 対 しても 行 え ます 上 と 同 じ 処 理 を 今 度 は JSP を 転 送 先 として 行 ってみましょう 以 下 の 手 順 にしたが って 作 成 してください 1 RadioButtonServlet2.java を 次 のように 修 正 します 下 線 部 が 修 正 箇 所 です <RadioButtonServlet2.java> public class RadioButtonServlet2 extends HttpServlet { String Sex=request.getParameter("Sex"); RequestDispatcher dispatcher; if(sex.equals("dansei")) { request.getrequestdispatcher("/input/dansei.jsp"); else { request.getrequestdispatcher("/input/josei.jsp"); dispatcher.forward(request, response); 2 input ディレクト 内 に 次 の dansei.jsp を 作 成 します radiobutton2.jsp を 別 名 保 管 して 修 正 しても 結 構 です <dansei.jsp> <%@page contenttype="text/html; charset=windows-31j"%> <HTML> <HEAD> <TITLE> 男 性 専 用 ページ</TITLE> </HEAD> <BODY> <H2> 男 性 専 用 ページ</H2> ようこそ 男 性 専 用 ページへ </BODY> </HTML> 3 dansei.jsp を 別 名 保 管 して josei.jsp を 作 成 します 修 正 内 容 は 男 性 専 用 ペー 91
ジ という 部 分 を 女 性 専 用 ページ に 変 更 することです 基 礎 課 題 7-3 作 成 したら 表 示 結 果 を 確 認 して 下 さい 表 示 結 果 を 確 認 したら 正 常 に 表 示 されました と 記 述 して 提 出 して 下 さい 7-2.リクエスト 属 性 の 追 加 前 節 では 入 力 パラメータを 受 け 取 ったサーブレットでは 出 力 表 示 の 処 理 をサーブレ ットあるいは JSP に 割 り 当 てる という 作 業 のみを 行 っていました 本 節 では サーブレ ットにおいて 新 たな 情 報 (データ)を 付 加 してから 処 理 を 割 り 当 てる 方 法 を 学 習 します 作 成 するのは 次 のような Web アプリケーションです 性 別 と 共 に 年 齢 を 入 力 する 成 年 未 成 年 に 関 するメッセージが 加 わる 以 下 の 手 順 にしたがって 基 礎 課 題 7-3 で 作 成 した Web アプリケーションを 修 正 し この Web アプリケーションを 作 成 してください 1 radiobutton2.jsp を 修 正 して radiobutton3.jsp として 別 名 保 管 してください 下 線 部 が 修 正 箇 所 です <%@page contenttype="text/html; charset=windows-31j"%> <HTML> <BODY> <H2>ラジオボタンからの 入 力 </H2> 性 別 を 選 び 年 齢 を 入 力 して 下 さい<br> <FORM ACTION="../RadioButtonServlet3" METHOD="POST"> <INPUT TYPE="RADIO" NAME="Sex" VALUE="Dansei"> 男 性 <INPUT TYPE="RADIO" NAME="Sex" VALUE="Josei"> 女 性 <br> 年 齢 <INPUT TYPE="TEXT" NAME="Age" ><br> <INPUT TYPE="SUBMIT" VALUE=" 送 信 "> <INPUT TYPE="RESET"> </FORM> </BODY> </HTML> 92
2 RadioButtonServlet2.java を 次 のように 修 正 して RadioButtonServlet3.java として 別 名 保 管 してください 下 線 部 と 枠 線 部 が 修 正 および 挿 入 箇 所 です <RadioButtonServlet3.java> public class RadioButtonServlet3 extends HttpServlet { String Sex=request.getParameter("Sex"); 挿 入 部 分 int Age=Integer.parseInt(request.getParameter("Age")); String Message=""; if(age>=20) { Message="あなたは 成 年 ですね "; else { Message="あなたは 未 成 年 ですね "; 下 の 解 説 参 照 request.setattribute("agemessage", Message); 解 説 RequestDispatcher dispatcher; if(sex.equals("dansei")) { request.getrequestdispatcher("/input/dansei3.jsp"); else { request.getrequestdispatcher("/input/josei3.jsp"); dispatcher.forward(request, response); setattribute( データ 名,データの 値 )という 形 式 で request にデータを 登 録 できます Attribute は 属 性 という 意 味 です ですから setattribute()によって request に 登 録 されているデータをリクエスト 属 性 と 言 います 93
3 dansei.jsp を 次 のように 修 正 して dansei3.jsp として 別 名 保 管 してください <%@page contenttype="text/html; charset=windows-31j"%> <HTML> <HEAD> <TITLE> 男 性 専 用 ページ</TITLE> </HEAD> <BODY> <H2> 男 性 専 用 ページ</H2> ようこそ 男 性 専 用 ページへ<br> <% String Message=(String) request.getattribute("agemessage"); %> <%= Message %> この 形 で AgeMassage というリクエスト </BODY> </HTML> 型 キャストが 必 要 今 の 場 合 は 文 字 列 型 へ 属 性 を 受 け 取 る <dansei3.jsp> 挿 入 部 分 4 dansei3.jsp を 修 正 して josei3.jsp として 別 名 保 管 してください 修 正 内 容 は 男 性 専 用 ページ の 部 分 を 女 性 専 用 ページ へ 変 更 することです 5 最 後 に web.xml に 次 のように RadioButtonServlet3 関 連 部 分 を 加 えます <web.xml> <web-app> 追 加 部 分 のみを 記 述 <servlet> <servlet-name>radiobuttonservlet3</servlet-name> <servlet-class>input.radiobuttonservlet3</servlet-class> </servlet> <servlet-mapping> <servlet-name>radiobuttonservlet3</servlet-name> <url-pattern>/radiobuttonservlet3</url-pattern> </servlet-mapping> </web-app> 基 礎 課 題 7-4 作 成 したら 表 示 結 果 を 確 認 して 下 さい 表 示 結 果 を 確 認 したら 正 常 に 表 示 されました と 記 述 して 提 出 して 下 さい 94
リクエスト 属 性 の 受 け 渡 しは サーブレットに 対 しても 行 えます そこで 確 認 のため に 今 度 はサーブレットへリクエスト 属 性 を 渡 しましょう 以 下 の 手 順 にしたがって 基 礎 課 題 7-4 で 作 成 した Web アプリケーションを 修 正 する 形 で 作 成 してください 1 RadioButtonServlet3.java を 次 のように 修 正 してください 下 線 部 が 修 正 箇 所 です <RadioButtonServlet3.java> public class RadioButtonServlet3 extends HttpServlet { String Sex=request.getParameter("Sex"); int Age=Integer.parseInt(request.getParameter("Age")); String Message=""; if(age>=20) { Message="あなたは 成 年 ですね "; else { Message="あなたは 未 成 年 ですね "; request.setattribute("agemessage", Message); RequestDispatcher dispatcher; if(sex.equals("dansei")) { request.getrequestdispatcher("/danseiservlet3"); else { request.getrequestdispatcher("/joseiservlet3"); dispatcher.forward(request, response); 2 次 のように DanseiServlet.java を 次 のように 修 正 して DanseiServlet3.java と 別 名 保 管 してください 下 線 部 と 枠 線 部 が 挿 入 箇 所 です getattribute()メソッド の 用 い 方 は JSP の 場 合 と 同 様 ですから 意 味 は 分 かると 思 います 95
<DanseiServlet3.java> public class DanseiServlet3 extends HttpServlet { response.setcontenttype("text/html;charset=windows-31j"); String AgeMessage= (String)request.getAttribute("AgeMessage"); PrintWriter out=response.getwriter(); out.println("<html>"); out.println("<head>"); out.println("<title> 男 性 専 用 ページ</TITLE>"); out.println("</head>"); out.println("<body>"); out.println("<h2> 男 性 専 用 ページ</H2>"); out.println("ようこそ 男 性 専 用 のページへ<br>"); out.println(agemessage); out.println("<body>"); out.println("</html>"); 3 DanseiServlet3.java を 修 正 して JoseiServlet3.java と 別 名 保 管 してください 修 正 は 男 性 専 用 ページ と 記 述 している 部 分 を 女 性 専 用 ページ に 変 更 する 事 で す 4 最 後 に web.xml に 次 ページのように Danseiservlet3 および JoseiServlet3 に 関 する 記 述 を 加 えてください 基 礎 課 題 7-5 作 成 したら 表 示 結 果 を 確 認 して 下 さい 表 示 結 果 を 確 認 したら 正 常 に 表 示 されました と 記 述 して 提 出 して 下 さい 96
<web.xml> <web-app> 追 加 部 分 のみを 記 述 <servlet> <servlet-name>danseiservlet3</servlet-name> <servlet-class>input.danseiservlet3</servlet-class> </servlet> <servlet> <servlet-name>joseiservlet3</servlet-name> <servlet-class>input.joseiservlet3</servlet-class> </servlet> <servlet-mapping> <servlet-name>danseiservlet3</servlet-name> <url-pattern>/danseiservlet3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>joseiservlet3</servlet-name> <url-pattern>/joseiservlet3</url-pattern> </servlet-mapping> </web-app> 7-3.インクルード(include)の 利 用 前 節 まで 学 習 したフォワード(forward)では 結 果 の 出 力 を 全 て 他 のサーブレットや JSP に 委 ねていました ところが 場 合 によっては 処 理 を 委 ねたサーブレット(JSP)と 分 担 して 呼 び 出 し 元 のサーブレットでも 結 果 の 出 力 を 行 いたい 場 合 があります そのような 場 合 フォワード(forward)ではなく インクルード(include)メソッドを 用 います 本 節 ではその 例 を 学 習 しましょう 作 成 する Web アプリケーションの 動 作 は 次 の 通 りです インクルード 先 で 表 示 インクルード 元 で 表 示 97
以 下 の 手 順 にしたがって Web アプリケーションを 作 成 してください 1 RadioButtonServlet3.java を 次 のように 修 正 してください 下 線 部 が 修 正 あるいは 挿 入 箇 所 です <RadioButtonServlet3.java> public class RadioButtonServlet3 extends HttpServlet { response.setcontenttype("text/html;charset=windows-31j"); String Sex=request.getParameter("Sex"); int Age=Integer.parseInt(request.getParameter("Age")); String Message=""; if(age>=20) { Message="あなたは 成 年 ですね "; else { Message="あなたは 未 成 年 ですね "; request.setattribute("agemessage", Message); RequestDispatcher dispatcher; if(sex.equals("dansei")) { request.getrequestdispatcher("/danseiservlet3"); else { request.getrequestdispatcher("/joseiservlet3"); forward()を include()に 変 更 dispatcher.include(request, response); PrintWriter out=response.getwriter(); out.println("<p> 規 約 を 守 って 本 ページを 利 用 して 下 さい </p>"); include()にすると 転 送 先 の 出 力 結 果 にこ こでの 表 示 結 果 を 加 える 事 が 可 能 になる 基 礎 課 題 7-6 作 成 したら 表 示 結 果 を 確 認 して 下 さい 規 約 を 守 って というメッセージが 新 たに 表 示 されたことを 確 認 したら 正 常 に 表 示 されました と 記 述 して 提 出 して 下 さい 98
7-4.リダイレクト(redirect)の 利 用 多 くの Web サイトでは URL が 変 更 になった 場 合 に それとは 知 らずにユーザが 旧 URL に 接 続 した 時 に 自 動 的 に 新 URL に 誘 導 するようになっています このときには リ ダイレクト(redirect)というメソッドが 用 いられています forward()メソッドでも 画 面 を 移 動 させることができますが 少 し 仕 組 みが 異 なります そこで 以 下 に forward()メソッ ドとの 違 いを 整 理 しておきましょう 1 p.90 の 基 礎 課 題 7-2 で 確 認 したように forward()メソッドの 場 合 は 転 送 先 の URL がクライアント(ブラウザ)に 表 示 されません 2 一 方 redirect()メソッドではクライアント(ブラウザ)を 所 定 のアドレスに 誘 導 する ので URL に 転 送 先 URL が 表 示 されます 3 また forward()メソッドを 用 いた 場 合 は request 属 性 や 入 力 パラメータを 転 送 先 に 引 き 継 ぐことができますが リダイレクトは 一 切 引 き 継 ぎません 4 したがって そのようなデータを 引 き 継 ぐ 必 要 のない 状 況 で 画 面 遷 移 を 行 いたい 場 合 に redirect()メソッドを 用 います 本 節 では redirect()メソッドを 用 いる 例 として 次 のように 入 会 資 格 のないユーザの 場 合 利 用 できない 旨 を 告 げるお 断 りのページに 誘 導 する 場 合 を 考 えましょう ここでは 会 員 資 格 を 男 女 共 に 13 年 齢 <60 としています リダイレクト 先 が 表 示 される 次 の 手 順 にしたがって この Web アプリケーションを 作 成 してください 1 RadioButtonServlet3.java を 次 ページのように 修 正 してください 枠 線 部 が 新 たに 挿 入 した 部 分 です ポイントは 次 の 通 りです redirect()メソッドは response オブジェクトに 所 属 しており redirect( 移 動 先 URL)の 形 で 用 います request.getcontextpath()メソッドは Web アプリケーションのルートパス を 求 めるメソッドです( 今 の 場 合 は /WebAppli ) 99
<RadioButtonServlet3.java> public class RadioButtonServlet3 extends HttpServlet { response.setcontenttype("text/html;charset=windows-31j"); String Sex=request.getParameter("Sex"); int Age=Integer.parseInt(request.getParameter("Age")); if(age<13 Age>=60) { response.sendredirect( request.getcontextpath()+"/input/warn.html" ); String Message=""; 挿 入 部 分 dispatcher.include(request, response); PrintWriter out=response.getwriter(); out.println("<p> 規 約 を 守 って 本 ページを 利 用 して 下 さい </p>"); 2 input フォルダ 内 に 次 のように Warn.html を 作 成 してください 以 前 に 作 成 し た JSP を 別 名 保 管 して 修 正 しても 結 構 です <HTML> <HEAD> <TITLE> 会 員 資 格 審 査 のページ</TITLE> </HEAD> <BODY> 申 し 訳 ありません あなたには 会 員 資 格 がありません </BODY> </HTML> <Warn.html> 基 礎 課 題 7-7 作 成 したら 表 示 結 果 を 確 認 して 下 さい 会 員 資 格 を 満 たしていない 年 齢 を 入 力 した 場 合 に p.99 のようなお 断 りのページが 出 ること そして URL がリダイレクト 先 になっている ことを 確 認 してください 確 認 したら 正 常 に 表 示 されました と 記 述 して 提 出 して 下 さい 100
7-5. 応 用 課 題 応 用 課 題 7-A - 基 礎 課 題 7-7 の 改 良 基 礎 課 題 7-7 で 作 成 した Web アプリケーシ ョンは 入 力 パラメータに 対 するチェックを 行 っ ていません そのため 最 初 の 画 面 で 次 のように 性 別 を 選 ばない あるいは 年 齢 を 記 入 せずに[ 送 信 ]ボタンをクリックすると エラーが 生 じてし まいます そこで きちんと 入 力 しなかった 場 合 は エラー 画 面 に 跳 んで 再 入 力 を 促 すように RadioButtonServlet3.java を 改 良 しましょう 作 成 する Web アプリケーションの 動 作 内 容 は 次 の 通 りです 101
1 RadioButtonServlet3.java を 次 のように 修 正 します 枠 線 部 は 追 加 部 分 です <RadioButtonServlet3.java> public class RadioButtonServlet3 extends HttpServlet { response.setcontenttype("text/html;charset=windows-31j"); String Sex=request.getParameter("Sex"); RequestDispatcher dispatcher2; String Error=""; lengh()メソッドは 文 字 列 の 長 さを 返 します この 値 が 0 の 場 合 は 文 字 列 が 空 っぽと いうことです if( Sex==null ) { 性 別 を 選 んでいない 場 合 のメッセージ Error=" 性 別 を 選 択 して 下 さい <br>"; if(request.getparameter("age").length()==0 ) { Error=Error+" 年 齢 を 入 力 して 下 さい "; 年 齢 を 入 力 していなかった 場 合 のメッセージ if(error.length()>0) { エラーメッセージが 存 在 する 場 合 の 処 理 request.setattribute("errmessage", Error); dispatcher2= request.getrequestdispatcher("/input/error.jsp"); dispatcher2.forward(request, response); else { エラーメッセージが 存 在 しない 場 合 の 処 理 従 来 の 処 理 int Age=Integer.parseInt(request.getParameter("Age")); if(age<13 Age>=60) { response.sendredirect( request.getcontextpath()+"/input/warn.html"); String Message=""; out.println("<p> 規 約 を 守 って 本 ページを 利 用 して 下 さい </p>"); 102
2 エラーメッセージを 表 示 する JSP error.jsp を input フォルダ 内 に 作 成 します <%@page contenttype="text/html; charset=windows-31j"%> <HTML> <HEAD> <error.jsp> <TITLE>エラーメッセージ</TITLE> </HEAD> <BODY> <H2>エラーメッセージ</H2> 入 力 エラーがあります <br> <p> <% String Error=(String) request.getattribute("errmessage"); %> <%= Error %> </p> もう 一 度 入 力 し 直 して 下 さい <A HREF="<%=request.getContextPath()%>/input/radiobutton3.jsp"> 入 力 ページ</A> </BODY> </HTML> 作 成 したら A) 性 別 を 選 んでない 場 合 ( 年 齢 は 入 力 ) B) 年 齢 を 入 力 していない 場 合 ( 性 別 は 選 択 ) C) 性 別 年 齢 いずれも 入 力 していない 場 合 の3つのケースについて 結 果 を 表 示 したブラウザ 画 面 のハードコピーをとり それぞれ Ouyou7_A_1.gif Ouyou7_A_2.gif Ouyou7_A_3.gif という 名 称 で 保 管 して 提 出 してください 103