JSP&Servlet/BASIC

페이지출력, 페이지전환 및 특정 url로 재 요청 을 해주는 RequestDispatcher 의 request.getRequestDispatcher()/forward() / HttpServletResponse의 response.sendRedirect()

유혁스쿨 2020. 8. 30. 03:02
728x90
반응형

# RequestDispatcher서블릿 forward(request, response)메서드

 

먼저 forward()와 sendRedirect의 개념차이를 아주 쉽게 구분하겠습니다.

 

forward() : 페이지 출력, 페이지 전환

sendRedirect() : 특정 url로 재 요청

 


# RequestDispatcher서블릿의 forward(request, response)메서드의 특징)

 

RequestDispatcher객체는 다른 페이지로 이동하는forward() 또는 include() 메소드를 가지고 있는 객체입니다.

(이때 다른 페이지로 이동한다는 것은 다른 뷰페이지 파일을 출력 해주는것 입니다) 

RequestDispatcher객체는 new연산자로 생성하는 것이 아니라, 메소드를 이용해서 생성해야 하는데, HttpServletRequest객체의 getRequestDispatcher()가 RequestDispatcher 객체를 생성해주는 메소드입니다.

        HttpServletRequest request= new HttpServletRequest();
        
        RequestDispatcher view = request.getRequestDispatcher(./member/mem_Login.jsp);
		view.forward(request,response);

혹은

	HttpServletRequset request = new HttpServletRequest();

	request.getRequestDispatcher("./member/mem_Login.jsp");.forward(request,response);

getRequestDispatcher()메소드의 인자값으로 이동할 페이지의 경로를 지정합니다.
내장객체 request을 통해 메서드를  호출하고 있습니다.


RequestDispatcher의 forward() 메서드는 페이지를 이동시키는 메서드입니다. 
이동하면서 현재페이지에서 사용하던 HttpServletRequest 와 HttpServletResponse 객체를 인자값으로 전달하는데,
내장객체인 request와 response를 넘겨주고 있습니다.

 

.getRequestDispatcher(); 메서드 안에 들어가는 문자열에는 뷰페이지경로.jsp가 들어갑니다.

뷰페이지 경로로 하는 경우는 기존 디비에 저장된 레코드값을 뷰페이지로 출력하는 경우입니다.
대표적으로 목록보기,수정폼,삭제폼,내용보기 가 있습니다.

물론 이때에는 값을 넘긴다하더라도 JSP파일에서 EL표현식과 JSTL을 사용하여 또다른 로직을 구현해야

넘겨받은 값을 출력시켜줄 수 있습니다. 

 

1. .forward(request,response) 두 객체는 해당주소에대해 요청하고 응답하라 라는 뜻이 담겨있다.
2. request.setAttribute()메서드로 저장된 키이름 값을 유지하려면 포워드로 이동해야한다.

3. 기존 매핑주소값을 유지하면서 해당 뷰페이지(view)경로인 member 폴더하위의 member_login.jsp파일로 이동합니다.

    해당경로(파일이름)은 숨겨집니다.
    실질적인 .의 기본 경로는 WebContent폴더가되고 . 은 WebContent폴더가됩니다.

     ./ 는 루트경로인 MVC 입니다

    member/member.jsp는 현재는 객체에 담겨져 있을 뿐 이고 member.jsp파일을 뷰로 보여줄 뿐입니다.

    member/member.jsp 는 주소창에서 대신 member/member.jsp 현재 해당 경로의 파일을 출력해 주고있는 메서드의      컨트롤러에 등록된 URI매핑주소로 대체됩니다.

    객체에 담겨져있는 루트경로는 주소창에 적용이되며 /루트경로/URI  -▷ /MVC/Member.do 이렇게 주소창에 표시됩      니다.
    스프링 상에서는 WebContent가 아니고 /WEB-INF/views경로가 지정됩니다. 
이경로는 뷰리졸브로 처리해주게 됩니      다.
4. request.setAttribute("키이름",값)에 의한 키이름에 저장된 값을 유지한다.
5. session.setAttribute("키이름",값) 로그인 인증한 세션 아이디값도 유지한다.

 

+번외로 getRequestDispatcher() 메서드 안에는 뷰페이지파일경로.jsp 뿐만아니라 url매핑주소 즉, uri주소를 담을수도 있습니다.

 

이때 uri가 /login이라고 등록된 컨트롤러에서 getRequsetDispatcher("/loginOk")메서드를 호출한다면

@WebServlet("/login")
public class Hello extends HttpServlet {
	private static final long serialVersionUID = 1L;
  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		RequestDispatcher rd = sc.getRequestDispatcher("/loginOk");
		rd.forward(request, response);    
		
	}
}

 

/loginOk이라는 매핑주소가 등록된 서블릿(Controller)의 doGet()메서드가 실행 되며 메서드에 들어있는 로직들이 수행된

@WebServlet("/loginOk")
public class Hello extends HttpServlet {
	private static final long serialVersionUID = 1L;
  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
        System.out.println("/loginOk 매핑주소에 접근되었습니다.");
		System.out.println("loginOk.jsp파일을 브라우저에 출력 시키겠습니다.");
		RequestDispatcher rd = sc.getRequestDispatcher("loginOk.jsp");
		rd.forward(request, response);    
		
	}
}

만약 이동된 uri의 컨트롤러 메서드 끝자락에서 getRequestDispatcher("loginOk.jsp")페이지를 불러들이게된다면 결국 loginOk.jsp 페이지를 띄우게 됩니다.

(페이지 전환, url주소 전환에 대한 요청은 기본적으로 GET방식으로 실행되며 이때, 주소창의 uri는 /loginOk로 전환되지 않고 처음 페이지전환을 실행하는 컨트롤러에 등록된 uri주소인 /login으로 유지가 됩니다.)

 

 

확실하게 어떤때에 쓰이는지는 모르겠으나 필요할때, 조건이 맞으면 uri를 적어서 사용도 할수 있는것 같습니다.

 


# response.sendRedirect(); 메서드의 특징)

 

응답을 클라이언트가 요청한 URL이 아니라 sendRedirect()에 주어진 URl로 재전송한다.  
이 메소드는 주로 서버의 특정 자원이 다른 URL로 이동할 때 사용할 수 있는 메서드입니다. 

 

redirect : 재 요청

redirect는 요청과 응답을 완료한 후 재요청을 합니다.

기본적으로 요청을 할때는 request(요청)와 response(응답)객체를 사용합니다.

재요청 할때는 request와 response객체를 사용 하고 재 요청을 하게 되면서 requset객체를 한번 더 만들어 처리합니다. 

 

가끔 때로는 redirect처리를 해야할 때가 있습니다. 
예를들어 글쓰기 요청이 끝난 후에 바로 글목록 페이지가 떠야합니다.  
바로 글목록페이지로 연결 해버리면 글목록을 띄우기위해서는 다시한번 DB에 접근해야합니다. 
select문을 돌린 후 insert된 게시물목록을 포함한 새롭게 목록이 갱신된 게시물목록을 가져와야합닌다. 
그렇다면 요청을 두번보내야 한다는것입니다. 
첫번째 요청은 insert 요청으로 게시물을 추가하는 처리를 해야하는 메서드 이후에  
두번째 요청은 select 요청으로 insert요청으로 추가한 게시글을 포함한  
새로운 목록을 갱신하여 가져오도록 처리하는 메서드로 요청을 한번 더 보내주는 것 입니다. 
  
글 삭제요청도 같습니다. 
delete요청을 보낸다음 DB에서 게시글을 지워버리고 삭제가 완료된 이후에 다시 글목록을 보여줄 때는 
삭제된 새로운 게시글 목록을 다시한번 DB를통해 수행해와야합니다. 
이럴때 다시한번 sendRedirect로 자동 재 요청을 보낸후 삭제가 갱신된 목록을 들고와야합니다. 

 

위에서 정리한 forward()는 한번의 요청만 해결을 해 버리는것 이고
요청이 두번들어가야 할 때가 있다는것입니다.
 
 입력후 목록요청
 -입력 후 입력된것을 적용한 목록으로 '재' 요청 
 삭제후 목록요청
 -삭제 후 삭제된것을 적용한 목록으로 '재' 요청

 

 

sendRedirect()메서드는 HttpServletResponse 의 객체로 호출이 가능합니다

 

/를 제외한 uri주소인 상대경로 login만 적거나 

public class LoginOKController extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	
        session.setAttribute("id", login_id);
    	response.sendRedirect("login");
    }
}

혹은 

public class LoginOKController extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	
        session.setAttribute("id", login_id);
    	response.sendRedirect("/web/response/login");
    }
}

contextPath경로부터 메서드의 경로까지인 절대경로 /web/response/login 이라고 입력해줘야합니다. 

 

 

sendRedirect();인자값으로 들어가는 내용은 URL매핑주소, URI주소가 됩니다. 
레코드를 저장/수정/삭제 후 변경된 디비 레코드 값을 다시 확인하고자 하는 경우 사용합니다. 
요청과 처리해주는 request,response 객체를 먼저 한번 처리후 재요청시에 다시 새롭게 만들어주고, 또 해당url매핑주소가 선언된 로직 메서드가 새로 실행되서 값들을 새로 받아와줍니다.

예외적으로 뷰페이지경로.jsp를 넣어줄 수도 있습니다.

 

1. sendRedirect("지정한 주소 또는 파일명") 메서드는 지정한 주소 또는 파일명으로 get방식으로 이동합니다.
2. session으로 저장된 로그인 인증 세션 아이디값을 잃어버리지 않는다. (저장할 다른매체가 있어서) 
   스프링 에서는 RedirectAttributes라는 새로운 객체를 생성,사용하여 서버저장으로 값을 넘겨줄수 있습니다.
3. 새로운 페이지로 레코드 저장, 수정, 삭제후 변경된 값을 다시 확인하고자 할 때 새로고침해서 새 페이지로 이동시킵     니다.
4. request.setAttribute("키이름",값) 메서드로 저장된 키이름값은 잃어버립니다.

   그렇기 때문에 저장후 넘겨야 할때 request를 대신하여 사용하는것으로는 HttpSession의 session에 대한객체를 생성     하고 담아줍니다.
5. sendRedirect를 주로 post방식으로부터 받아온 후 해당 방식에서 사용될 때가 많아 기본값이 Post->get으로 전환되     는줄 오해하지만 해당 메서드의 방식과는 상관없이 post에서쓰였다면 post->get 이고 get에서 쓰였다면 get->get이      됩니다. (get에서도 쓰일수 있다는 얘기)
6. 주로 값을 저장하거나 수정 후 이전페이지로 돌아갔을때 내용이 새롭게 변경될때 사용합니다.

 


sendRedirect("뷰페이지파일경로.jsp") / forward("/url매핑주소")

 

다른 페이지로 전환하거나 주소를 재요청할때 사용되는것은 각각 getRequestDispatcher().forward() / sendRedirect()를 사용합니다

근데 다른 페이지전환 즉 다른 페이지를 출력할때 getRequestDispatcher()메서드 인자값으로 ("뷰페이지파일경로.jsp") 이렇게 넣어줍니다

그리고 sendRedirect()를할때는 인자값으로 ("uri주소 혹은 url매핑주소") 뭐 절대경로든 상대경로든 주소를입력해주고요 그 주소를 재요청해줍니다.

 

근데... 이거...

forward일때는 getRequestDispatcher에 뷰페이지파일경로.jsp만 쓰이는게아니라 /매핑주소를 넣어줘도 조건이 맞으면 작동이 되고

sendRedirect()를 할때도 /매핑주소 뿐만아니라 뷰페이지파일경로.jsp 라고 써도 조건이 맞으면 작동이 되긴 됩니다...

 

 

sendRedirect("/url매핑주소") / forward("뷰페이지파일경로.jsp") 코드가

sendRedirect("뷰페이지파일경로.jsp") / forward("/url매핑주소") 이렇게도 조건이 맞을때에는 작동이 된다는것입니다... 

 

우선 

forward는 페이지 전환에 대한 한번의 요청일때 사용해 버리는것 이고

sendRedirect는 페이지든 주소가 되었든 요청이 두번들어가야 할 때 사용한다는것  

즉,  

입력후 목록요청 - 입력 후 입력된것을 적용한 목록 요청 

삭제후 목록요청 - 삭제 후 삭제된것을 적용한 목록 요청

 

이런 재요청이 필요한 시점에 사용한다고 쉽게 정의할수있고

 

이 때에 매핑주소를 넣는 이유는  그 매핑주소가 등록된 서블릿(컨트롤러)의 doGet()메서드에 접근하게되는거고

그 메서드에 들어있는 로직들을 처리한다음 Attribute로 값을담아서 마지막쯤에 페이지 전환시켜주고 값도 넘기고 한다는건데

그러면..음... foward일때 매핑주소로 처리되있다면 매핑주소로 접근해서 get방식의 메서드에있는 어떠한 로직들을 처리하고 

전환될 페이지? 혹은 전환될 url로 값을 반환하면서 또 넘어가겠죠? 

 

그럼 sendRedirect()는 재요청을해주는건데 만약에 sendRedirect("뷰페이지파일경로.jsp") 이렇게 인자값을 뷰페이지경로.jsp 이라고 했다면 

대체 어떨때.. 

무슨 작업을 하기위해sendRedirect("뷰페이지파일경로.jsp") 이렇게 sendRedirect()안에 매핑주소가 아닌 뷰페이지경로.jsp를 쓰는지가 궁금합니다...

 

머리가 나빠서 어떨때 쓰이는거지? 이런생각까지는 응용이 안되네요....

아시는분들께서는 댓글로 도와주십시요... 부탁드립니다.... 

 

 

 

 

728x90
반응형