第8章 サーブレット間の連携
サーブレット間の連携
homepage
# **サーブレット間の連携** *** ## **1.インクルード(include)** 複数のサーブレット間で強調して処理を行う方法を確認していきます。<br> まずはサーブレット内に他のサーブレットの処理をインクルードする方法です。<br> 例えば、サーブレットAが呼ばれ、レスポンスに対して出力をしている途中でサーブレットBをインクルードしたとします。そうするといったんサーブレットBへ処理が移った後でサーブレットBの処理が終わったら呼び出し元のサーブレットAへ処理が戻り、残りの処理を行うと言った感じです。<br> インクルードを行うには、まずRequestDispatcherインターフェースのオブジェクトを作成する必要があります。このオブジェクトはクライアントからのリクエストをディスパッチ(他へ委譲する)ためのものです。<br> オブジェクトを作成するには、"HttpServletRequest"インターフェースの親インターフェースである ServletRequestインターフェースで定義されている"getRequestDispatcher"メソッドを使います。<br> **getRequestDispatcher** ``` public RequestDispatcher getRequestDispatcher(java.lang.String path) ``` 引数には委譲先のファイルやサーブレットのパスを指定します。例えばこの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 ``` "include"メソッドの引数には、呼び出し元のサーブレットの"doGet"メソッドや"doPost"メソッドが呼び出された時に引数に指定されている値をそのまま渡します。<br> 利用方法としては下記のようになります。 ``` public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String disp = "/includetest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.include(request, response); } ``` #### **例** **DispatchTest.java** ``` package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/IncludeTestDispatchTest") public class DispatchTest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=UTF-8"); 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>"); } } ``` **IncludeTest.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; @WebServlet("/IncludeTest") public class IncludeTest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<p style='background:#ff0000'>"); out.println("インクルードファイル内で処理されています"); out.println("</p>"); } } ``` #### **実行結果** <!--graph8-1.png --> <img src="https://i.loli.net/2019/07/01/5d19c6058460a91913.png" width="40%" /> ## **2.フォワード(forward)** インクルードと似ていますがフォワードの場合は処理をフォワード先のサーブレットに移してしまいますので、呼び出し元のサーブレットには処理は戻って来ません。また呼び出し元の方ではレスポンスに対する出力も行えません。その為、呼び出し元の方で何らかの処理を行った上で、処理をフォワード先のサーブレットに完全に移す場合に利用します。<br> フォワードは、元のサーブレットへ送られてきたパラメータなども含めてフォワード先のサーブレットへそのままフォワードします。その為、クライアントからはサーブレット内部でフォワードされたことに気が付かないまま、フォワード先のサーブレットからの出力を受け取ります。<br> フォワードを行う場合にも **"RequestDispatcher"** インターフェースのオブジェクトを作成する必要があります。手順はインクルードの場合と同じです。<br> 例えばWebアプリケーションのパスが「/dispatch」でフォワード先のサーブレットが「/dispatch/forwardtest」だった場合は次のようになります。<br> ``` 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 ``` "forward"メソッドの引数も、呼び出し元のサーブレットの"doGet"メソッドや"doPost"メソッドが呼び出された時に引数に指定されている値をそのまま渡します。<br> 利用方法としては下記のようになります。 ``` public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String disp = "/forwardtest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); } ``` #### **例** **WebContent/html/Forwardtest1.html** ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>フォワードテスト</title> </head> <body> <form action="../DispatchTest1" method="post"> <table border="1"> <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** ``` package servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; @WebServlet("/DispatchTest1") 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("UTF-8"); String[] seibetsu = request.getParameterValues("seibetsu"); if (seibetsu[0].equals("男性")){ String disp = "/ForwardDansei1"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); }else{ String disp = "/ForwardJosei1"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); } } } ``` **ForwardDansei1.java** ``` package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/ForwardDansei1") public class ForwardDansei1 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("UTF-8"); 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** ``` package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/ForwardJosei1") public class ForwardJosei1 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("UTF-8"); 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>"); } } ``` #### **実行結果** <!--graph8-2.png --> <a href="https://i.loli.net/2019/07/01/5d19c75051b8a36472.png" target="_blank"><img src="https://i.loli.net/2019/07/01/5d19c75051b8a36472.png" width="40%"/></a> <br> <!--graph8-3.png --> <img src="https://i.loli.net/2019/07/01/5d19cd579dbd651781.png" width="40%"/> リクエストへの属性追加フォワードなどを行う際に、フォワード先に何か別の情報を合わせて渡すことができます。クライアントから送られてきたリクエストをフォワード先に渡す前に、リクエストに属性を追加することで実現します。<br> 追加する場合には「HttpServletRequest」インターフェースの親である「ServletRequest」インターフェースで定義されている"setAttribute"メソッドを使います。<br> **setAttribute** ``` public void setAttribute(java.lang.String name, java.lang.Object o) ``` "**setAttribute**"メソッドを使うことで、リクエストに新しい属性名と値をセットすることが出来ます。<br> 次に追加した属性を取り出す場合です。"**getAttribute**"メソッドを使います。 **getAttribute** ``` public java.lang.Object getAttribute(java.lang.String name) ``` "**getAttribute**"メソッドの引数に属性名を指定すれば、対応する値を取り出すことができます。利用方法としては下記のようになります。<br> ``` public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ request.setAttribute("Hantei", "Out"); String disp = "/forwardtest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); } ``` #### **例** **WebContent/html/Forwardtest2.html** ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>フォワードテスト</title> </head> <body> <form action="../DispatchTest2" method="post"> <table border="1"> <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> ``` **DispatchTest2.java** ``` package servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/DispatchTest2") public class DispatchTest2 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); //PrintWriter out = response.getWriter(); request.setCharacterEncoding("UTF-8"); String nensyu = request.getParameter("nensyu"); int nensyu_val = Integer.parseInt(nensyu); if (nensyu_val < 2000000) { request.setAttribute("hantei", "貧乏ですね"); } else { request.setAttribute("hantei", "大丈夫でしょう"); } String disp = "/ForwardTest2"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); } } ``` **ForwardTest2.java** ``` package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/ForwardTest2") public class ForwardTest2 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("UTF-8"); out.println("<html>"); out.println("<head>"); out.println("<title>ディスパッチ</title>"); out.println("</head>"); out.println("<body>"); String toshi = request.getParameter("toshi"); String nensyu = request.getParameter("nensyu"); String hantei = (String) request.getAttribute("hantei"); out.println("<p>"); out.println("年齢:" + toshi + ", 年収" + nensyu); out.println("</p>"); out.println("<p>"); out.println("年収判定:" + hantei); out.println("</p>"); out.println("</body>"); out.println("</html>"); } } ``` #### **実行結果** <!--graph8-4.png --> <img src="https://i.loli.net/2019/07/01/5d19cc3b095ad95194.png" width="40%"/> <br> <!--graph8-5.png --> <img src="https://i.loli.net/2019/07/01/5d19cc3b17c0d95441.png" width="40%"/> ## **3.リダイレクト(redirect)** リダイレクトは他のサーブレットやHTMLファイルに処理を移します。フォワードと似ていますが、フォワードはサーバ内で次のサーブレットなどへ処理を移しますが、リダイレクトの場合はクライアントに対してリダイレクト先のサーブレットなどを見に行くように指示を出すだけです。その為、クライアント側でも処理が別のページ移ったことを認識します。<br> またフォワードの場合はクライアントから送られ来たパラメータなどを含むリクエストをそのままフォワード先に移しますが、リダイレクトの場合は次の見るべきサーブレットやHTMLファイルなどをクライアントに指示するだけですのでクライアントから送られてきたリクエストの中身などはリダイレクト先には渡されません。<br> 例えば何かの処理をしてエラーだった場合にはエラーページへ飛ばすとか、データベースの処理だけをするサーブレットを呼び出した後に処理が終わったらサーブレットでは何も出力を行わずに特定のページへ飛ばすなどに使います。リダイレクトの場合には、別のサーバにあるURLへ飛ばすことも可能です(フォワードの場合は同一サーバ内しか行えません)。<br> リダイレクトするには「HttpServletResponse」インターフェースで定義されている"sendRedirect"メソッドを使います。 **sendRedirect** ``` public void sendRedirect(java.lang.String location) throws java.io.IOException ``` "sendRedirect"メソッドの引数にはリダイレクトしたいURLを指定します。<br> 利用方法としては下記のようになります。 ``` public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String url = "/dispatch/redirecttest"; response.sendRedirect(url); } ``` #### **例** **RedirectTest3.java** ``` package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/RedirectTest3") public class RedirectTest3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); log("アクセスされました"); String url = "ServletDoc/html/redirect.html"; response.sendRedirect(url); } } ``` **WebContent/html/redirect.html** ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>リダイレクトテスト</title> </head> <body> <p>こんにちは</p> </body> </html> ``` #### **実行結果** <!--graph8-6.png --> <img src="https://i.loli.net/2019/07/01/5d19ceb7c364483998.png" width="40%" />
content
戻る