전달하는 데이터의 양이 적을 때에는 GET 방식을 통해 포워딩 해 주는 것이 편하다. 하지만, 데이터의 양이 많으면 비효율적이기 때문에 바인딩을 사용한다.
사용자가 웹 페이지의 폼을 통해 이름과 이메일 주소를 입력하고 제출 버튼을 누르면, 이름과 이메일 정보를 서버로 보낸 다음 서버가 데이터를 처리해야 한다. 이 때, 사용자가 입력한 이름과 이메일 주소를 자바 코드 내에서 다루기 쉬운 형태로 만들어 주는 것이 데이터 바인딩이다. 즉, 받은 데이터를 자바 객체에 넣어 주는 것이 바인딩인 것이다. 아래 예시가 있다.
public class User {
private String name;
private String email;
}
여기서, 데이터 바인딩을 사용하면 사용자가 입력한 이름과 이메일 주소를 자동으로 User 객체의 name과 email 필드에 넣어주는 것이다.
공부 중, '데이터베이스에 저장하는 것'도 데이터 바인딩이 아닐까 하는 의문점이 들었다. 내가 생각하기에 데이터를 가공하려면 DB에 저장을 먼저 해야 한다고 생각했기 때문이다. 하지만, 데이터를 가공하는 것과 DB에 저장하는 것은 다른 의미이다. DB에 저장하는 것은, 가공된 데이터를 영구적으로 보존하거나 나중에 검색하고 수정이 쉽도록 하기 위해 하는 것이기 때문이다.
| 관련 메소드 | 기능 |
|---|---|
| setAttribute(String name, Object obj) | 자원(데이터0을 각 객체에 바인딩 |
| getAttribute(String name) | 각 객체에 바인딩된 자원(데이터)을 name으로 가져옴 |
| removeAttribute(String name) | 각 객체에 바인딩된 자원(데이터)을 name으로 제거함 |
@WebServlet("/first6")
public class FirstServlet6 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
request.setAttribute("address", "서울시 성북구"); //웹 브라우저에서 요청한 request 객체에 address 값으로 서울시 성북구를 바인딩
response.sendRedirect("second6"); //두 번째 서블릿으로 전달하기 위함
}
}
@WebServlet("/second6")
public class SecondServlet6 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String address = (String)request.getAttribute("address"); //전달된 request에서 getAttribute()를 이용해 address의 값을 가져옴
out.println("<html><body>");
out.println("주소:"+address);
out.println("redirect를 이용한 바인딩 실습입니다.");
out.println("<body></html>");
}
}
근데 위의 코드를 실행해 보면 '서울시 성북구'가 출력되어야 하는데 null이 출력된다. 각각 서블릿에 대한 request는 총 두 개가 있다. 첫 번째로는 클라이언트가 /first6 경로로 서버에 요청을 보내는 것이고, 두 번째 요청은 redirection을 통해 클라이언트가 /second6 경로로 서버에 요청을 보내는 것이다. 이 두 개의 request는 서로 다른 요청이기 때문에 redirect 방식으로는 서블릿에서 바인딩한 데이터를 다른 서블릿으로 전송할 수 없는 것이다.
@WebServlet("/first7")
public class FirstServlet7 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
request.setAttribute("address", "서울시 성북구"); //브라우저의 최초 요청 request에 바인딩
RequestDispatcher dispatch = request.getRequestDispatcher("second"); //바인딩된 request를 다시 두 번째 서블릿으로 포워드
dispatch.forward(request, response);
}
}
@WebServlet("/second7")
public class SecondServlet7 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String address = (String) request.getAttribute("address"); //전달된 request에서 getAttribute()를 이용해 주소를 받아옴
out.println("<html><body>");
out.println("주소:" + address);
out.println("<br>");
out.println("dispatch를 이용한 바인딩 실습입니다.");
out.println("</body></html>");
}
}
위의 방식 대로 하면 정상적으로 address값이 출력된다. 첫 번째 서블릿에서 두 번째 서블릿으로 전달되는 request가 브라우저를 거치지 않고 바로 전달된 사실을 알 수 있다. 즉, request에 바인딩된 데이터가 그대로 전달된 것이다.
| redirect | dispatch |
|---|---|
| 새로운 url을 거침 | 서버 내부에서 전달함 |
| 새로운 요청이 발생하므로 이전 요청에서 설정한 속성값이 전달되지 않음 | 하나의 요청과 응답이 유지되므로 요청에서 설정한 속성이 유지됨 |