フォワード(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"メソッドを使ってフォワードします。

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ファイルをまず用意します。

forwardtest.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>

次にフォームから呼び出されれるサーブレットです。

DispatchTest1.java

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つのサーブレットです。

ForwardDansei1.java

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>");
  }
}

ForwardJosei1.java

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」へアクセスしてみます。

forward

HTMLのフォームが表示されますので適当な値を入力して「送信する」ボタンをクリックして下さい。

forward

まずフォームで指定されたサーブレットが呼び出されます。そのサーブレット内でまず性別の値を取り出し性別によってフォワード先を決めます。今回は男性がフォームで入力されていましたので、男性用のサーブレットが呼び出されています。

フォワードの場合は、フォワード先で元のリクエストに含まれていたパラメータを取得できますので、フォワード先のサーブレットで年齢と年収の値を読み取り表示しています。

では改めてHTMLファイルに戻り、次のように入力して下さい。

forward

今度は性別を女性にしてみます。「送信する」ボタンをクリックして下さい。

forward

性別が女性でしたので、女性用のサーブレットへフォワードされています。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。