sendRedirect VS RequestDispatcher
1. sendRedirect / encodeRedirectURL
client의 브라우저에게 매개변수로 등록한 페이지를 재요청하라고 응답해주는 것(301/302코드 전송)
encodeRedirectURL은 매개변수(URL)에 세션ID정보를 추가 재요청 처리
client가 별도로 다른 페이지 요청을 안해도 url주소(페이지)가 변경됨.
** 브라우저가 알아서 서버에 해당 페이지를 요청
쿼리스트링으로 별도의 데이터를 전송하지 않으면 요청데이터가 없음
Rrdirect 테스트
html )
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>redirect</title>
</head>
<body>
<h1 align="center">redirect</h1>
<a href="othercite">다른 웹사이트로 redirect 테스트</a>
<br>
<a href="otherservlet">다른 서블릿으로 redirect 테스트</a>
</body>
</html>
Servlet )
1) 다른 웹사이트로 redirect 테스트
@WebServlet("/othercite")
public class OtherCiteRedirectSrevlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("get 요청후 naver 사이트로 redirect");
/* 브라우저의 개발자 도구 network 탭을 보면 302번 status code와 함께
* naver 사이트로 이동한 것을 볼 수 있다
* 사용자 url 재작성이라고 불리는 redirect 방식은 302번 코드인 경우 요청에 대한 처리를 잘 했으며
* 사용자의 url을 강제적으로 redirect 경로로 이동시키라는 의미이다.*/
response.sendRedirect("http://www.naver.com");
}
}
2) 다른 서블릿으로 redirect 테스트
@WebServlet("/otherservlet")
public class OtherServletRedirectTest extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("get 요청 정상 수락");
response.sendRedirect("redirect");
}
}
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("이 서블릿으로 redirect 성공!");
StringBuilder redirectText = new StringBuilder();
redirectText.append("<!doctype html>")
.append("<html>")
.append("<head>")
.append("<head>")
.append("<body>")
.append("<h1>이 서블릿으로 redirect 성공! </h1>")
.append("</body>")
.append("</html>");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(redirectText);
out.flush();
out.close();
}
}
redirect를 하는 경우 url이 재작성 되어 새로 고침해도 redirect된 페이지에 대한 요청만을 반복한다.
즉, 이전 요청에 남아있던 정보는 더이상 남아 있지 않게된다. 또한 url도 변경 된다.
http 요청은 요청 시에 잠시 connection을 맺고 응답 시에도 잠시 connection을 맺으며
요청 단위 당 request 객체는 한 개만 생성이 된다.
따라서 첫 요청 시의 request와 redirect된 페이지의 request는 서로 다른 객체이다.
그렇기 때문에 redirect를 이용하게 되면 이전 서블릿의 값을 공유해서 사용할 수 없게 된다.
그럼 redirect시 값을 유지하는 방법은? 크게 쿠키와 세션이라는 것을 이용할 수 있다. (다음 포스팅에 작성)
2. RequestDispatcher() ~ forward()
컨테이너 내에서 처음 요청 받은 페이지가 요청 데이터 (HttpServletRequest, HttpServletResponse)를
다른 페이지에 전송하여 처리를 요청을 하고 자신이 처리한 것처럼 하는 것. url주소(페이지)가 변경되지 않음.
forward 테스트
html )
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>forward</title>
</head>
<body>
<h1 align="center">forward</h1>
<form action="forward" method="post">
<table align="center">
<tr>
<td>아이디</td>
<td><input type="text" name="userId"></td>
<td rowspan=2><button type="submit" style="height:50px;">로그인</td>
</tr>
<tr>
<td>비밀번호</td>
<td><input type="password" name="password"></td>
</tr>
</table>
</form>
</body>
</html>
Servlet )
forward 받은 서블릿에서도 요청 방식이 get이면 doGet 메소드를, 요청 방식이 post이면 doPost 메소드를 호출한다.
request에 이전 서블릿에서 전달하고자 하는 정보를 담았기 때문에 해당 서블릿에서는 다시 꺼내온다.
@WebServlet("/print")
public class PrintLoginSuceeessServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userId = (String)request.getAttribute("userId");
System.out.println("forward 확인 : " + userId);
/* 응답에 필요한 데이터가 다 준비 되면 동적인 웹 페이지를 생성한다. */
StringBuilder responseText = new StringBuilder();
responseText.append("<!doctype html>\n")
.append("<html>\n")
.append("<head>\n")
.append("</head>\n")
.append("<body>\n")
.append("<h3 align='center'>")
.append(userId)
.append("님 환영합니다.</h3>")
.append("</body>\n")
.append("</html>");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(responseText.toString());
out.flush();
out.close();
}
}
변수의 기본 스코프는 메소드(page)이기 때문에 다른 페이지(서블릿)으로 데이터 공유 불가
forward 방식은 request와 response를 넣어서 위임하므로 request에 정보를 저장하여
forward 했을 경우 위임 당한 서블릿에서도 서블릿의 정보를 공유할 수 있게 된다.
또한 forward 방식은 해당 서블릿의 존재를 client가 알 필요가 없어 url 자체가 변경 되지 않는다.
단, 서버로 전송한 데이터가 남아있는 상태로 새로고침(재요청)을 하게되면 요청을 계속 반복하게 되어
DB에 insert하는 행위가 반복 되어 중복 행이 발생하는 등의 문제가 있을 수 있다.
이러한 경우는 또 다른 페이지 전환 방식 sendRedirect를 사용해야 한다.
서블릿 데이터 공유
객체별 공유 데이터 설정
객체 | 사용 메소드 | 내용 |
ServletContext ServletRequest HttpSession |
setAttribute(String,Object) | 공유값을 저장 |
getAttribute(String) | 공유값을 불러옴 | |
getAttributeName() | 공유값 전체를 불러옴 | |
removeAttribute(String) | 공유값 자체를 지움 |
** 공유값은 Map형식으로 저장됨.
'백엔드 과정 > Servlet' 카테고리의 다른 글
[Servlet] file.io (0) | 2022.03.07 |
---|---|
[Servlet] cookie와 session (0) | 2022.03.07 |
[Servlet] Response 응답 확인하기 (0) | 2022.03.06 |
[Servlet] GET/POST 방식에 따른 서블릿 메소드 (0) | 2022.03.05 |
[Servlet] 서블릿 라이프 사이클 (0) | 2022.03.04 |