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