Одной из распространеных задач веб-программирования является переадресация. Рассмотрим, как мы можем в сервлетах выполнять переадресацию на другой ресурс.
Метод forward() класса RequestDispatcher позволяет перенаправить запрос из сервлета на другой сервлет, html-страницу или страницу jsp. Причем в данном случае речь идет о перенаправлении запроса, а не о переадресации.
Например, пусть в проекте определена страница index.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Servlets in Java</title> </head> <body> <h2>Index.html</h2> </body> </html>
Данная страница просто выводит заголовок.
И, допустим, мы хотим из сервлета перенаправить запрос на эту страницу:
import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; 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("/hello") public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = "/index.html"; ServletContext servletContext = getServletContext(); RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path); requestDispatcher.forward(request, response); } }
Для того, чтобы выполнить перенаправление запроса, вначале с помощью метода getServletContext()
получаем объект
ServletContext, который представляет контекст запроса. Затем с помощью его метода getRequestDispatcher()
получаем объект RequestDispatcher. Путь к ресурсу, на который надо выполнить перенаправление, передается в качестве параметра в getRequestDispatcher.
Затем у объекта RequestDispatcher вызывается метод forward(), в который передаются объекты HttpServletRequest и HttpServletResponse.
И если мы обратимся к сервлету, то фактически мы получим содержимое страницы index.html, который будет перенаправлен запрос.
Подобным образом мы можем выполнять перенаправление на страницы jsp и другие сервлеты. Например, добавим в проект новый сервлет NotFoundServlet:
Определим для NotFoundServlet следующий код:
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("/notfound") public class NotFoundServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter writer = response.getWriter(); String id = request.getParameter("id"); try { writer.println("<h2>Not Found: " + id + "</h2>"); } finally { writer.close(); } } }
В данном случае NotFoundServlet сопоставляется с адресом "/notfound".
Изменим код HelloServlet, чтобы он перенаправлял на NotFoundServlet:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; 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("/hello") public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = "/notfound"; ServletContext servletContext = getServletContext(); RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path); requestDispatcher.forward(request, response); } }
В данном случае если id равен null, то идет перенаправление на NotFoundServlet. Следует отметить, что в метод requestDispatcher.forward
передаются объекты HttpServletRequest и HttpServletResponse. То есть NotFoundServlet
получит те же самые данные запроса, что и HelloServlet.
Для переадресации применяется метод sendRedirect() объекта HttpServletResponse. В качестве параметра данный метод принимает адрес переадресации. Адрес может быть локальным, внутренним, а может быть и внешним.
Например, если сервлету HelloServlet не передано значение для параметра id, выполним переадресацию на сервлет NotFoundServlet:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; 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("/hello") public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); if(id == null) { String path = request.getContextPath() + "/notfound"; response.sendRedirect(path); } else { response.setContentType("text/html"); PrintWriter writer = response.getWriter(); try { writer.println("<h2>Hello Id " + id + "</h2>"); } finally { writer.close(); } } } }
В данном случае переадресация идет на локальный ресурс. Но важно понимать, что в метод sendRedirect передается адрес относительно корня
текущего домена. То есть в данном случае у нас домен и порт http://localhost:8001/, а приложение называется helloapp,
то для обращения к сервлету NotFoundServlet необходимо передать адрес "helloapp/notfound". Путь к текущему приложению можно получить с помощью
метода getContextPath()
.
Также можно выполнять и переадресацию на внешний ресурс, указывая полный адрес:
response.sendRedirect("https://metanit.com/");