インクルード(include)
ここからは複数のサーブレット間で強調して処理を行う方法を確認していきます。
まずはサーブレット内に他のサーブレットの処理をインクルードする方法です。
例えば、サーブレットAが呼ばれ、レスポンスに対して出力をしている途中でサーブレットBをインクルードしたとします。そうするといったんサーブレットBへ処理が移った後でサーブレットBの処理が終わったら呼び出し元のサーブレットAへ処理が戻り、残りの処理を行うと言った感じです。
インクルードを行うには、まず"RequestDispatcher"インターフェースのオブジェクトを作成する必要があります。このオブジェクトはクライアントからのリクエストをディスパッチ(他へ委譲する)ためのものです。
オブジェクトを作成するには、"HttpServletRequest"インターフェースの親インターフェースである"ServletRequest"インターフェースで定義されている"getRequestDispatcher"メソッドを使います。
getRequestDispatcher public RequestDispatcher getRequestDispatcher(java.lang.String path)
Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. A RequestDispatcher object can be used to forward a request to the resource or to include the resource in a response. The resource can be dynamic or static. The pathname specified may be relative, although it cannot extend outside the current servlet context. If the path begins with a "/" it is interpreted as relative to the current context root. This method returns null if the servlet container cannot return a RequestDispatcher. The difference between this method and ServletContext.getRequestDispatcher(java.lang.String) is that this method can take a relative path. Parameters: path - a String specifying the pathname to the resource. If it is relative, it must be relative against the current servlet. Returns: a RequestDispatcher object that acts as a wrapper for the resource at the specified path, or null if the servlet container cannot return a RequestDispatcher
引数には委譲先のファイルやサーブレットのパスを指定します。例えばこのWebアプリケーションのパスが「/dispatch」でインクルードしたいサーブレットが「/dispatch/includetest」だった場合は次のようになります。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String disp = "/includetest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); }
ディスパッチャーが作成できましたら、「RequestDispatcher」インターフェースで定義されている"include"メソッドを使って外部へ処理を委譲します。
include public void include(ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException
Includes the content of a resource (servlet, JSP page, HTML file) in the response. In essence, this method enables programmatic server-side includes. The ServletResponse object has its path elements and parameters remain unchanged from the caller's. The included servlet cannot change the response status code or set headers; any attempt to make a change is ignored. 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 contains the client's request response - a ServletResponse object that contains the servlet's response Throws: ServletException - if the included resource throws this exception java.io.IOException - if the included resource throws this exception
"include"メソッドの引数には、呼び出し元のサーブレットの"doGet"メソッドや"doPost"メソッドが呼び出された時に引数に指定されている値をそのまま渡します。
利用方法としては下記のようになります。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String disp = "/includetest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.include(request, response); }
サンプルプログラム
では簡単に試してみます。
今回作成するWebアプリケーションのパスは「dispatch」とし、Webアプリケーションの置き場所は「d:\servlet-sample\dispatch\」としました。コンテキストファイルは下記のようになります。
<Context path="/dispatch" docBase="d:/servlet-sample/dispatch"/>
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>DispatchTest</servlet-class> </servlet> <servlet> <servlet-name>includetest</servlet-name> <servlet-class>IncludeTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatchtest</servlet-name> <url-pattern>/dispatchtest</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>includetest</servlet-name> <url-pattern>/includetest</url-pattern> </servlet-mapping> </web-app>
プログラムは下記の通りです。
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class DispatchTest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>ディスパッチ</title>"); out.println("</head>"); out.println("<body>"); out.println("<p>この下の部分がインクルードで処理されています</p>"); String disp = "/includetest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.include(request, response); out.println("<p>この上の部分がインクルードで処理されています</p>"); out.println("</body>"); out.println("</html>"); } }
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class IncludeTest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); out.println("<p style=\"background:#ff0000\">"); out.println("インクルードファイル内で処理されています"); out.println("</p>"); } }
上記をコンパイル後に「d:\servlet-sample\dispatch\WEB-INF\classes\」ディレクトリにクラスファイルを移動した後で、ブラウザで「http://localhost:8080/dispatch/dispatchtest」へアクセスしてみます。
分かりやすいようにインクルードされたサーブレットで処理された部分は背景を赤くしてあります。
このようにインクルードとはサーブレットの処理中に別のサーブレットへ処理を移し、そして元の処理に戻ってくることになります。あたかもサーブレット内に別のサーブレットを挿入して処理しているようになります。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。