2022-11-17 MVC, 요청 재지정
[MVC]
< 실습3 >
- list.jsp : 사원 목록 리스트에서 id를 누르면 사원 정보가 나오는 read only페이지로 이동하고, '수정'버튼을 누르면 사원 정보를 수정할 수 있는 페이지로 이동하기
<td><a href="/serverweb/mvc/read.do?id=<%=user.getId()%>&action=READ"><%=user.getId()%></a></td>
//EmpReadServlet.java
=> action=READ : action이라는 변수에 "READ"라는 데이터를 넣어 "/serverweb/mvc/read.do" 파일로 파라미터로 넘김
String view = "";
if(action.equals("READ")) {
view = "/mvc/emp_read.jsp";
}else {
view = "/mvc/emp_update.jsp";
}
RequestDispatcher rd = req.getRequestDispatcher(view); //view로 이동됨
rd.forward(req, resp);
=> 만약 action의 값이 "READ"라면 "/mvc/emp_read.jsp"로 이동 → emp_read.jsp의 수행결과 화면으로 응답함. 그 외의 값은 "/mvc/emp_update.jsp"로 요청 재지정하여 emp_update.jsp의 수행결과를 응답함.
< 실습4 >
- emp_update : 위에서 수정페이지로 이동했다면 이제 데이터를 수정하여 처리하는 작업을 진행.
<body>
<%
empDTO user = (empDTO)request.getAttribute("user");
%>
<div class="container-fluid">
<form role="form" class="form-horizontal"
action="/serverweb/mvc/update.do" method="post">
<fieldset>
<div class="form-group">
<label class="control-label col-sm-2" for="id">아이디</label>
<div class="col-sm-3"> <%=user.getId()%>
<input type="hidden" name="id" value="<%=user.getId()%>">
</div>
=> 주소, 패스워드, 포인트, 등급, 아이디(id는 정보가 보이지 않도록 hidden타입으로)의 파라미터를 "EmpUbdateServlet.java"으로 넘겨준다.
//1. 클라이언트 요청정보 추출
String id = req.getParameter("id");
String pass = req.getParameter("pass");
String addr = req.getParameter("addr");
int point = Integer.parseInt(req.getParameter("point"));
int grade = Integer.parseInt(req.getParameter("grade"));
//2. 비지니스메소드 호출
empDAO dao = new empDAO();
empDTO dto = new empDTO(id, pass, addr, point, grade);
int result = dao.update(dto);
//3. 데이터공유
req.setAttribute("user", dto);
//4. 요청재지정
String view = "";
if(result > 0) {
view = "/serverweb/mvc/list.do"; //수정 성공하면 리트스화면으로 넘어가도록
}else {
view = "/serverweb/mvc/read.do?=id="+id+"&action=UPDATE"; // 수정 실패하면 업데이트 화면이 보여지도록
}
resp.sendRedirect(view);
//EmpUbdateServlet.java
=> getParameter로 넘겨준 값을 받아 update메소드를 호출하고, 요청 재지정을 하기 위해 데이터를 공유해준다.
여기서 요청 재지정으로 sendRedirect를 사용한 이유는 update작업 후에 데이터를 공유해줄 것이 없기 때문이다.
그래서 sendRedirect를 사용해 우선 요청에 대한 응답으로 다른 응답 코드와 재요청할 자원에 대한 URL정보를 응답해준다. 그 방법을 얻어 두 번째 재요청을 하면 요청 재지정한 주소의 수행결과를 대신 응답하게 하는 것이다.
@WebServlet(name = "mvclist",urlPatterns = {"/mvc/list.do"})
public class EmpListServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
System.out.println("서블릿요청성공");
//1. 클라이언트 요청정보 추출
req.setCharacterEncoding("UTF-8");
//2. 비지니스메소드 호출
empDAO dao = new empDAO();
ArrayList<empDTO> allList = dao.select();
System.out.println("메소드 호출해서 결과 받아옴"+allList);
//3. 데이터공유
req.setAttribute("allList", allList);
//4. 요청재지정 - forward
RequestDispatcher rd = req.getRequestDispatcher("/mvc/list.jsp"); //이동할 페이지의 경로 지정. list.jsp로 이동됨
rd.forward(req, res);
}
}
==> 쉽게 말하면 클라이언트가 a약국에 갔는데 a약국에선 "우리 약국에는 없으니 b약국으로 한 번 가보세요." 라고 응답한 것이다. 클라이언트는 응답받은 내용을 참고해 b약국으로 다시 가서 약을 받아오는 방식이다.
forward와 redirect의 차이점
forward는 클라이언트가 요청 재지정된 사실을 모르지만 redirect는 그 사실을 알 수 있다.
forward는 서버에서 모든 걸 처리하여 응답하지만 redirect는 클라이언트를 거치기 때문이다.
그렇기 때문에 forward는 객체를 공유하여 데이터를 주고 받고, redirect는 객체를 공유하지 않아
서로가 존재하는지도 모른다. 즉, 객체를 공유한다는 것은 동일 웹 어플리케이션 자원만 사용할 수 있다는 뜻이고,
공유하지 않는다는 것은 요청재지정 대상이 없으므로 자유롭다는 것이다.