こんにちは!ゼネットの中川です。
今回はリダイレクトとフォワードの違いと使い方について説明していこうと思います。
この記事はこんな人におすすめです。
- Java Servletの勉強してるけど、リダイレクトとフォワードって何?
- どんな時にリダイレクトとフォワードを使うの?
私も研修でリダイレクトとフォワードの違いが分からなかったのですが、理解を深めることができたので紹介したいと思います。
結論
- 渡すデータがなく、同じアプリケーションの別機能を使い画面に遷移したい場合はリダイレクトを使うといい
- JSP、サーブレット、HTMLに状態を遷移したい場合はフォワードを使うといい
実際にどんな問題点からこのような結論がでたのかコードを使いながら説明していきます。
研修中であった出来事
今までページの遷移の時はフォワードを利用して演習を解いていました。しかし、回答例を見たときにリダイレクトを用いて実装をしていました。
回答と見比べたときに気づいたこととして同じような処理を2つ書いていたことが分かかりました。
今回は簡単なソースコードを利用して状況を説明したいと思います。
最初に自分自身が作ったコードです。
自分の回答
ServletA
package controller; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletA extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String word = "Hello World"; req.setAttribute("word", word); RequestDispatcher dispatcher = req.getRequestDispatcher("initialScreen.jsp"); dispatcher.forward(req, resp); } }
ServletB
package controller; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletB extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String word = "Hello World"; req.setAttribute("word", word); RequestDispatcher dispatcher = req.getRequestDispatcher("initialScreen.jsp"); dispatcher.forward(req, resp); } }
JSP
<!DOCTYPE HTML> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>初期画面</title> <meta charset = "UTF-8"> </head> <body> <h1>初期画面</h1> <% String word = (String)request.getAttribute("word"); %> <p><%= word %></p> <form action = "./ServletB" method = "POST"> <input type = "submit" value = "送信"> </form> </body> </html>
Web.xml
<web-app> <servlet> <servlet-name>ServletA</servlet-name> <servlet-class>controller.ServletA</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletA</servlet-name> <url-pattern>/ServletA</url-pattern> </servlet-mapping> <servlet> <servlet-name>ServletB</servlet-name> <servlet-class>controller.ServletB</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletB</servlet-name> <url-pattern>/ServletB</url-pattern> </servlet-mapping> </web-app>
画面
実際にフォワードを利用してJSPに遷移するようにしたものです。ServletAとServletBを見てみると同じような処理をしていることが分かると思います。流れとしては
URL→ServletA→JSP→送信ボタンを押す→ServletB→JSP
次に回答のServletBを見てみると
回答のServletB
回答は
package controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletB extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("./ServletA"); } }
URL→ServletA→JSP→送信ボタンを押す→ServletB→ServletA→JSP
と遷移するといった流れになりました。
画面で見たときは見た目は同じなのですが、フォワードの場合同じ処理をしているというのが分かると思います。
次にフォワードとリダイレクトの説明とメリット、デメリットを説明します。
リダイレクト説明
リダイレクトは最初ユーザからリクエストが送られ、サーバはユーザに対してこのURLでリクエストを返してと返します。
その後、もう一度ユーザはサーバから言われたURLでリクエストをし、サーバが処理をするという流れになっています。
リダイレクトをするメリットとしては
- 外部サーバのページに移動できる
また、デメリットとしては
- リクエスト、レスポンスを2往復するので、性能的に悪い
- リクエストスコープに値を格納しても、データを渡すことができない
フォワード説明と使用例
フォワードの場合はユーザからのリクエストが送られてきたあと、サーバはユーザに対してレスポンスを返すという流れになっています。
フォワードをする上でのメリットは
- リダイレクトと比べ通信の往復が少ないので性能的に優れている
- リクエスト情報を引き継ぐことができる
- JSP、サーブレット、HTMLでも遷移先に指定することができる
デメリットは
- URLが遷移先画面で変化しない
まとめ
- 渡すデータがなく、同じアプリケーションの別機能を使い画面に遷移したい場合はリダイレクトを使うといい
- JSP、サーブレット、HTMLに状態を遷移したい場合はフォワードを使うといい
今回の例題ではフォワードの時に短い処理を2回違うサーブレットで同じ処理を書いていました。今回は短い処理でしたが、データベース処理や他のクラスを利用するなどの処理が増えると冗長になり後々困ってくると思います。
リダイレクトとフォワードの違いを理解して使いこなせるようになりましょう!