フォワード(forward)
次はフォワードです。インクルードと似ていますがフォワードの場合は処理をフォワード先のサーブレットに移してしまいますので、呼び出し元のサーブレットには処理は戻って来ません。また呼び出し元の方ではレスポンスに対する出力も行えません。その為、呼び出し元の方で何らかの処理を行った上で、処理をフォワード先のサーブレットに完全に移す場合に利用します。
フォワードは、元のサーブレットへ送られてきたパラメータなども含めてフォワード先のサーブレットへそのままフォワードします。その為、クライアントからはサーブレット内部でフォワードされたことに気が付かないまま、フォワード先のサーブレットからの出力を受け取ります。
フォワードを行う場合にも"RequestDispatcher"インターフェースのオブジェクトを作成する必要があります。手順はインクルードの場合と同じです。
例えばWebアプリケーションのパスが「/dispatch」でフォワード先のサーブレットが「/dispatch/forwardtest」だった場合は次のようになります。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String disp = "/forwardtest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); }
ディスパッチャーが作成できましたら、「RequestDispatcher」インターフェースで定義されている"forward"メソッドを使ってフォワードします。
forward public void forward(ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException
Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. This method allows one servlet to do preliminary processing of a request and another resource to generate the response. For a RequestDispatcher obtained via getRequestDispatcher(), the ServletRequest object has its path elements and parameters adjusted to match the path of the target resource. forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward. The request and response parameters must be either the same objects as were passed to the calling servlet's service method or be subclasses of the ServletRequestWrapper or ServletResponseWrapper classes that wrap them. Parameters: request - a ServletRequest object that represents the request the client makes of the servlet response - a ServletResponse object that represents the response the servlet returns to the client Throws: ServletException - if the target resource throws this exception java.io.IOException - if the target resource throws this exception java.lang.IllegalStateException - if the response was already committed
"forward"メソッドの引数も、呼び出し元のサーブレットの"doGet"メソッドや"doPost"メソッドが呼び出された時に引数に指定されている値をそのまま渡します。
利用方法としては下記のようになります。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String disp = "/forwardtest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); }
サンプルプログラム
では簡単に試してみます。
web.xmlファイルは下記のようにしました。
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <servlet> <servlet-name>dispatchtest</servlet-name> <servlet-class>DispatchTest1</servlet-class> </servlet> <servlet> <servlet-name>forwarddansei</servlet-name> <servlet-class>ForwardDansei1</servlet-class> </servlet> <servlet> <servlet-name>forwardjosei</servlet-name> <servlet-class>ForwardJosei1</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatchtest</servlet-name> <url-pattern>/dispatchtest</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>forwarddansei</servlet-name> <url-pattern>/forwarddansei</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>forwardjosei</servlet-name> <url-pattern>/forwardjosei</url-pattern> </servlet-mapping> </web-app>
プログラムは下記の通りです。今回はHTMLファイルからフォームを使ってサーブレットへ送信するテストを行いますので、一番最初に呼び出すHTMLファイルをまず用意します。
<html> <head> <title>フォワードテスト</title> </head> <body> <form action="/dispatch/dispatchtest" method="post"> <table border="0"> <tr> <td>年齢</td><td><input type="text" size="10" value="" name="toshi"></td> </tr> <tr> <td>年収</td><td><input type="text" size="10" value="" name="nensyu"></td> </tr> <tr> <td>性別</td><td><select name="seibetsu"> <option>男性</option> <option>女性</option> </select></td> </tr> <tr> </table> <input type="submit" VALUE="送信する"> <input type="reset" VALUE="リセット"> </form> </body> </html>
次にフォームから呼び出されれるサーブレットです。
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class DispatchTest1 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("Shift-JIS"); String[] seibetsu = request.getParameterValues("seibetsu"); if (seibetsu[0].equals("男性")){ String disp = "/forwarddansei"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); }else{ String disp = "/forwardjosei"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); } } }
次にフォワード先である2つのサーブレットです。
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ForwardDansei1 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("Shift-JIS"); out.println("<html>"); out.println("<head>"); out.println("<title>ディスパッチ</title>"); out.println("</head>"); out.println("<body>"); String[] toshi = request.getParameterValues("toshi"); String[] nensyu = request.getParameterValues("nensyu"); out.println("<p>"); out.println("男性用ホームページです"); out.println("</p>"); out.println("<p>"); out.println("年齢:" + toshi[0] + ", 年収" + nensyu[0]); out.println("</p>"); out.println("</body>"); out.println("</html>"); } }
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ForwardJosei1 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("Shift-JIS"); out.println("<html>"); out.println("<head>"); out.println("<title>ディスパッチ</title>"); out.println("</head>"); out.println("<body>"); String[] toshi = request.getParameterValues("toshi"); String[] nensyu = request.getParameterValues("nensyu"); out.println("<p>"); out.println("女性用ホームページです"); out.println("</p>"); out.println("<p>"); out.println("年齢:" + toshi[0] + ", 年収" + nensyu[0]); out.println("</p>"); out.println("</body>"); out.println("</html>"); } }
上記をコンパイル後に「d:\servlet-sample\dispatch\WEB-INF\classes\」ディレクトリにクラスファイルを移動した後で、ブラウザで「http://localhost:8080/dispatch/forwardtest.html」へアクセスしてみます。
HTMLのフォームが表示されますので適当な値を入力して「送信する」ボタンをクリックして下さい。
まずフォームで指定されたサーブレットが呼び出されます。そのサーブレット内でまず性別の値を取り出し性別によってフォワード先を決めます。今回は男性がフォームで入力されていましたので、男性用のサーブレットが呼び出されています。
フォワードの場合は、フォワード先で元のリクエストに含まれていたパラメータを取得できますので、フォワード先のサーブレットで年齢と年収の値を読み取り表示しています。
では改めてHTMLファイルに戻り、次のように入力して下さい。
今度は性別を女性にしてみます。「送信する」ボタンをクリックして下さい。
性別が女性でしたので、女性用のサーブレットへフォワードされています。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。