화면 이동 방식 🍑 Redirect VS Forwarding VS Session VS Context 🍑

Yeppi's 개발 일기·2022년 5월 25일
0

Servlet&JSP

목록 보기
8/13
post-custom-banner

1. 리디렉트 Redirect

2번의 request와 2번의 response

  • 요청 URL 변경됨
  • 데이터 공유 불가

📌예시📌

  • a는 요청할 때 reuest 만들어졌다가 사라짐
  • b를 요청할 떄 다시 request 를 생성
@WebServlet("/servletA.do")
public class AServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("nickName", "Gurum");
		response.sendRedirect("servletB.do");
	}
}
@WebServlet("/servletB.do")
public class BServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String nickName = (String) context.getAttribute("nickName"); 
		System.out.println("별명 : " + nickName);
	}
	
}
  • url에 a 호출, b 호출
  1. 브라우저가 servletA.do 를 요청

  2. 해당 클래스의 매개변수 requestsetAttribute()로 데이터 지정

  3. Redirect 리디렉트을 이용하여 servletB.do를 요청하도록
    response을 이용하여 브라우저에게 전달

  4. 전달(응답)이 끝난 브라우저는 servletA.dorequest가 없어짐

  5. 브라우저가 servletB.do에게 request를 다시 요청

  6. nickName 에 해당하는 String 값이 현재 없기 때문에
    null 을 브라우저에 출력


👉 servletA.do, servletB.do 는 데이터 추출 불가



2. 포워딩 Forwarding

1번의 request와 1번의 response

  • 요청 URL 변경 안됨

  • 한 번의 요청/응답 👉 실행 속도 빠름

  • request 매개변수를 통해 데이터 공유


📌예시📌

  • a에 저장된 request 를 b에 전달
@WebServlet("/servletA.do")
public class AServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("nickName", "Gurum");
		RequestDispatcher dispatcher = request.getRequestDispatcher("servletB.do");
		dispatcher.forward(request, response);
	}
	
}
@WebServlet("/servletB.do")
public class BServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String nickName = (String) context.getAttribute("nickName"); 
		System.out.println("별명 : " + nickName);
	}
	
}
  • url에 a 호출, b 호출
  1. 브라우저가 servletA.do 를 요청

  2. 해당 클래스의 매개변수 requestsetAttribute()로 데이터 지정

  3. Dispatcherforward 포워딩하여 servletB.do 를 호출

  4. servletB.do 에서 저장된 request와 동일한 키워드가 있는 지 확인

  5. nickName 에 해당하는 String 값을 브라우저에 출력


👉 servletA.do, servletB.do 는 데이터를 공유



3. 세션 Session

브라우저가 살아있는 시간 동안


📌예시📌

  • a에 세션 객체를 담고, b에서 사용
  • 리디렉트 관계에 있는 서블릿 사이에서 정보 공유하기 위해 HttpSession 사용
@WebServlet("/servletA.do")
public class AServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession(); // 세션에 담기
		request.setAttribute("nickName", "Gurum");
		response.sendRedirect("servletB.do");
	}
}
@WebServlet("/servletB.do")
public class BServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String nickName = (String) session.getAttribute("nickName"); // 세션에서 빼오기
		System.out.println("별명 : " + nickName);
	}
	
}
  • 처음 브라우저 실행하면 null, 그 뒤로는 계속 Gurum 출력

    • request.getSession() 할 때마다 해당 객체가 매번 생성되진 않음 ⇒ 재사용

    • 다만 리디렉트이므로, 주소가 바뀜


  1. 브라우저가 servletA.do 를 요청

  2. 해당 브라우저의 session 값을 추출해서 저장

  3. 해당 세션 객체에 setAttribute() 로 데이터 지정

  4. Redirect 리디렉트을 이용하여 servletB.do를 요청하도록
    response을 이용하여 브라우저에게 전달

  5. 이때 request 정보는 세션 객체에 저장되어 있으므로
    브라우저가 종료할 때까지 servletA.dorequest 는 없어지지 않음

  6. 전달(응답)받은 브라우저는 servletA.do 에서 세션 객체에 저장된 데이터가 있는 찾음

  7. servletA.donickName 키워드로 저장된 데이터 Gurum 을 브라우저에게 응답


👉 servletA.do, servletB.do 는 리디렉트 방식이지만 세션 객체로 데이터를 공유



4. Servlet Context

브라우저가 종료해도 서블릿 컨테이너가 살아있는 동안

  • 서블릿 컨텍스트 = 서블릿 컨테이너 개념
  • Servlet Container 가 죽지 않으면?
    Servlet Context 에 저장된 정보를 다 쓸 수 있음

  • Servlet Container 가 죽을 때?
    톰캣 서버도 stop 됨

  • ServletContext 객체는
    브라우저가 종료해도 사용 가능

  • HttpServletRequest 객체는
    브라우저가 서버에 요청할 때 생성 + 응답보내는 순간 삭제

👉 따라서, 브라우저와 상관없이 계속 사용할 데이터는? 세션이 아닌, 컨텍스트에 저장하기


📌예시📌

  • 브라우저와 무관하게 정보저장하기
@WebServlet("/servletA.do")
public class AServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext context = getServletContext(); // getServletContext() 부모로부터 상속된 메서드
		context.setAttribute("nickName", "Gurum");
	}
	
}
@WebServlet("/servletA.do")
public class AServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext context = getServletContext(); // getServletContext() 부모로부터 상속된 메서드
		context.setAttribute("nickName", "Gurum");
	}
	
}
  • 브라우저 출력 결과는 위 세션과 동일

  • 다만, 세션은 브라우저 종료 or 로그아웃 시
    저장된 HttpSession 객체가 자동 삭제

  • 컨텍스트는 브라우저를 종료했다가 다시 키더라도
    ServletContext 객체에 저장된 데이터는 유효함


👉 servletA.do, servletB.do 는 서버에 데이터가 저장되어서 데이터 공유



🍑한눈에 정리🍑

HttpServletRequest < HttpSession < ServletContext


Web 기본적인 동작 방식과 방식들 간의 차이점에 대해 알 수 있어서 좋았다.

profile
imaginative and free developer. 백엔드 / UX / DATA / 기획에 관심있지만 고양이는 없는 예비 개발자👋
post-custom-banner

0개의 댓글