-
[Back End] Redirect & ForwardWeb Development/부스트코스 - Back-End(Java) 2020. 3. 6. 21:54
Reirect(리다이렉트)
- 서버가 클라이언트에게 특정 URL로 이동하라는 요청을 보내는 것을 리다이렉트라고 한다.
- 리다이렉트는 HTTP 프로토콜로 정해진 규칙이다.
- 서버는 클라이언트에게 HTTP 상태 코드 302로 응답하는데 이때 헤더 내 Location 값에 이동할 URL을 추가한다. 클라이언트는 리다이렉션 응답을 받게 되면 헤더(Location)에 포함된 URL로 재요청을 보내게 된다. 이때 브라우저의 주소창은 새 URL로 바뀌게 된다.
- 서블릿이나 JSP는 리다이렉트를 하기 위해 HttpServletResponse 클래스의 sendRedirect() 메서드를 사용한다.
예제
- 두 개의 JSP 파일 redirect01.jsp, redirect02.jsp이 있다.
- redirect01.jsp는 redirect02.jsp로 리다이렉트 한다.
redirect01.jsp
- response 객체의 sendRedirect() 메소드를 사용한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% response.sendRedirect("redirect02.jsp"); %>
redirect02.jsp
- 다른 기능없이 "redirect 된 페이지입니다."를 화면에 출력한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> redirect된 페이지 입니다. </body> </html>
예제 동작 설명
- 웹 브라우저는 서버에 두 번의 요청을 보낸다.
- 첫 번째 요청의 request, response 객체는 두 번째 요청(리다이렉트)의 request, response 객체와 당연히 다르다.
브라우저에서 리다이렉트 확인
- 아래 보면 redirect01.jsp 의 응답 코드는 302인 것을 관찰할 수 있다.
Forward
- WAS의 서블릿이나 JSP가 요청을 받은 후 그 요청을 처리하다가, 추가적인 처리를 같은 웹 애플리케이션 안에 포함된 다른 서블릿이나 JSP에게 위임할 수 있다. 이를 포워드(forward)라고 한다.
1. 웹 브라우저(클라이언트)에서 Servlet1에게 요청을 보낸다.
2. Servlet1은 요청을 처리한 후, 그 결과를 HttpServletRequest에 저장한다.
3. Servlet1은 결과라 저장된 HttpServletRequest와 응답을 위한 HttpServletResponse를 같은 웹 애플리케이션 안에 있는 Servlet2에게 전송한다.(forward)
4. Servlet2는 Servlet1으로 부터 받은 HttpServletRequest와 HttpServletResponse를 이용하여 요청을 처리한 후 웹 브라우저에게 결과를 전송한다.
- 위의 예시에서 클라이언트 요청에 대한 request 객체와 response 객체는 각각 1개뿐이다. 요청을 한 번 보냈기 때문에 당연하다.
예제
FrontServlet.java
package examples; 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("/front") public class FrontServlet extends HttpServlet { private static final long serialVersionUID = 1L; public FrontServlet() { super(); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int diceValue = (int)(Math.random() * 6) + 1; request.setAttribute("dice", diceValue); //랜덤 주사위 값을 request 객체에 넘겨준다. RequestDispatcher requestDispatehcer = request.getRequestDispatcher("/next"); requestDispatehcer.forward(request, response); // "/next"(NextServlet)로 forward } }
NextSevlet.java
package examples; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; 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("/forward") public class ForwardServlet extends HttpServlet { private static final long serialVersionUID = 1L; public ForwardServlet() { super(); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head><title>form</title></head>"); out.println("<body>"); int dice = (Integer)request.getAttribute("dice"); // FrontServlet에서 받은 랜덤 추사위 값을 활용한다. out.println("dice : " + dice); for(int i = 0; i < dice; i++) { out.print("<br>hello"); } out.println("</body>"); out.println("</html>"); } }
Servlet과 JSP연동
- Servlet과 JSP는 서로 상호 보완적인 관계를 가지고 있다.
- Servlet은 로직을 구현하기에 알맞지만, HTML을 출력하기엔 불편하다.
- Servlet은 프로그램 로직이 수행되기에 유리하다. Servlet은 모두 자바코드임.
- JSP는 로직을 구현하기에 불편하지만, HTML을 출력하기엔 편하다.
- JSP는 결과를 출력하기에 서블릿보다 유리하다. 필요한 HTML문을 그냥 입력하면 된다.
- Servlet과 JSP의 장단점을 해결하기 위해서 Servlet에서 프로그램 로직이 수행되고, 그 결과를 JSP에게 포워딩하는 방법이 사용되게 되었다. 이를 Servlet과 JSP 연동이라고 한다.
예제
LogicServlet.java
package examples; 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("/LogicServlet") public class LogicServlet extends HttpServlet { private static final long serialVersionUID = 1L; public LogicServlet() { super(); // TODO Auto-generated constructor stub } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int v1 = (int)(Math.random() * 100) + 1; int v2 = (int)(Math.random() * 100) + 1; int result = v1 + v2; request.setAttribute("v1", v1); //request 객체에 "v1"이라는 이름으로 v1 변수값 저장 request.setAttribute("v2", v2); //request 객체에 "v2"이라는 이름으로 v2 변수값 저장 request.setAttribute("result", result); //request 객체에 "result"이라는 이름으로 result 변수값 저장 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/result.jsp"); requestDispatcher.forward(request, response); //RequestDispatcher 객체를 사용해 JSP로 forward } }
result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% int v1 = (int)request.getAttribute("v1"); //LogicServlet에서 request 객체에 담아보낸 v1,v2,result 값 활용 int v2 = (int)request.getAttribute("v2"); int result = (int)request.getAttribute("result"); %> <%=v1%> + <%=v2 %> = <%=result %> //표현식을 사용해 화면에 출력 </body> </html>
'Web Development > 부스트코스 - Back-End(Java)' 카테고리의 다른 글
[Back End] JDBC - 실습 (0) 2020.03.14 [Back End] JDBC (0) 2020.03.14 [Back End] JSTL, EL, Maven (0) 2020.03.09 [Back End] Scope (0) 2020.03.07 [Back End] JSP 기초 (0) 2020.03.05