프로그래밍 언어/자바 웹

바인딩

· 코딩마이데이

서블릿에서 다른 서블릿 또는JSP로 대량의 데이터를 공유하거나 전달하고 싶을 때는 바인딩(binding) 기능을 사용헙니다.

바인딩의 사전적 의미는 "두 개를 하나로 묶는다"는 것입니다. 이는 웹 프로그램 실행 시 자원(데이터)을 서블릿 관련 객체에 저장하는 방법으로, 주로 HttpServletRequest, HttpSession, ServeltContext 객체에서 사용되며 저장된 자원(데이터)은 프로그램 실행 시 서블릿이나 JSP에서 공유하여 사용합니다.

실제 모델2, 스트릿츠, 스프링 프레임워크로 구현하는 웹 프로그램은 이 바인딩 기능을 이용해 서블릿이나 JSP 간 데이터를 전달하고 공유합니다.

 

서블릿 객체에서 사용되는 바인딩 메서드

관련 메서드 기능
setAttribute(String name, Object obj) 자원(데이터)을 각 객체에 바인딩합니다.
getAttribute(String name) 각 객체에 바인딩된 자원(데이터)을 name으로 가져옵니다.
removeAttribute(String name) 각 객체에 바인딩된 자원(데이터)을 name으로 제거합니다.

 

HttpServletRequest를 이용한 redirect 포워딩 시 바인딩

 

1. 다음과 같이 실습 과정을 준비합니다.

실습 파일 위치

 

2. FirstServlet 클래스를 다음과 같이 작성합니다. HttpServletRequest의 setAttribute() 메서드를 이용해 (address, "서울시 성북구")를 바인딩합니다.

package sec04.ex01;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/first")
public class FirstServlet 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", "서울시 성북구");
		response.sendRedirect("second");
	}
}

 

3. 두 번째 서블릿에서는 HttpServletRequest의 getAttribute() 메서드를 이용해 전달된 주소를 받습니다.

package sec04.ex01;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/second")
public class SecondServlet 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");
		out.println("<html><body>");
		out.println("주소:" + address);
		out.println("<br>");
		out.println("redirect를 이용한 바인딩 실습입니다.");
		out.println("</body></html>");
	}
}

 

4. 실행 결과를 보면 정상적으로 '서울시 성북구'가 출력되어야 하는데 null이 출력됩니다.

매핑 이름 first로 요청한 결과

 

redirect 방식으로는 서블릿에서 바인딩한 데이터를 다른 서블릿으로 전송할 수 없다는 것입니다.

 

HttpServletRequest를 이용한 dispatch 포워딩 시 바인딩

1. 다음과 같이 실습 파일을 준비합니다.

실습 파일 위치

 

2. FirstServlet 클래스를 다음과 같이 작성합니다. 브라우저에서 전달된 request에 주소를 바인딩한 후 dispatch 방법을 이용해 다른 서블릿으로 포워딩합니다.

package sec04.ex02;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/first")
public class FirstServlet 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", "서울시 성북구");
		RequestDispatcher dispatch = request.getRequestDispatcher("second");
		dispatch.forward(request, response);
	}
}

 

3. SecondServlet 클래스를 다음과 같이 작성합니다. 전달된 request에서 주소를 받은 후 브라우저로 출력합니다.

package sec04.ex02;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/second")
public class SecondServlet 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");
		out.println("<html><body>");
		out.println("주소:" + address);
		out.println("<br>");
		out.println("dispatch를 이용한 바인딩 실습입니다.");
		out.println("</body></html>");
	}
}

 

4. 이번에는 화면에 정상적으로 주소가 출력됩니다.

dispatch 방법으로 바인딩된 데이터 전달

 

 

두 서블릿 간 회원 정보 조회 바인딩 실습

1. MemberDAO와 MemeberVO 클래스를 만들고, 데이터베이스 연동을 위한 DataSource 기능도 설정합니다.

package sec04.ex03;

import java.sql.Date;

public class MemberVO {
	private String id;
	private String pwd;
	private String name;
	private String email;
	private Date joinDate;
	
	public MemberVO()
	{
		System.out.println("MemberVO 생성자 호출");
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Date getJoinDate() {
		return joinDate;
	}

	public void setJoinDate(Date joinDate) {
		this.joinDate = joinDate;
	}
}

 

package sec04.ex03;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class MemberDAO {
	private PreparedStatement pstmt;
	private Connection con;
	private DataSource dataFactory;
	
	public MemberDAO() {
		try {
			Context ctx = new InitialContext();
			Context envContext = (Context) ctx.lookup("java:/comp/env");
			dataFactory = (DataSource) envContext.lookup("jdbc/oracle");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public List<MemberVO> listMembers()
	{
		List<MemberVO> list = new ArrayList<MemberVO>();
		try {
			con = dataFactory.getConnection();
			String query = "select * from t_member";
			System.out.println("prepareStatement: "+ query);
			pstmt = con.prepareStatement(query);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next())
			{
				String id = rs.getString("id");
				String pwd = rs.getString("pwd");
				String name = rs.getString("name");
				String email = rs.getString("email");
				Date joinDate = rs.getDate("joinDate");
				MemberVO vo = new MemberVO();
				vo.setId(id);
				vo.setPwd(pwd);
				vo.setName(name);
				vo.setEmail(email);
				vo.setJoinDate(joinDate);
				list.add(vo);
			}
			rs.close();
			pstmt.close();
			con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
}

ojdbc6.jar 추가
Server - Tomcat - context.xml 파일

 

 

 

2. MemberServlet 클래스를 다음과 같이 작성합니다. 첫 번째 서블릿에서 조회한 회원 정보를 List에 저장한 후 다시 바인딩하여 두 번째 서블릿으로 전달합니다.

package sec04.ex03;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet("/member")
public class MemberServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;chatset=utf-8");
		PrintWriter out = response.getWriter();
		MemberDAO dao = new MemberDAO();
		List memberList = dao.listMembers();
		request.setAttribute("membersList", memberList);
		RequestDispatcher dispatch = request.getRequestDispatcher("viewMembers");
		dispatch.forward(request, response);
	}
}

 

2. ViewServlet 클레스를 다음과 같이 작성합니다. getAttribute() 메서드를 이용해 첫 번째 서블릿에서 바인딩한 회원 정보를 List로 가져옵니다.

package sec04.ex03;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;

@WebServlet("/viewMembers")
public class ViewServlet 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();
		List membersList = (List) request.getAttribute("membersList");
		out.print("<html><body>");
		out.print("<table border=1><tr align='center' bgcolor='lightgreen'>");
		out.print("<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td><td>가입일</td><td >삭제</td></tr>");
		for (int i = 0; i < membersList.size(); i++) {
			MemberVO memberVO = (MemberVO) membersList.get(i);
			String id = memberVO.getId();
			String pwd = memberVO.getPwd();
			String name = memberVO.getName();
			String email = memberVO.getEmail();
			Date joinDate = memberVO.getJoinDate();
			out.print("<tr><td>" + id + "</td><td>" + pwd + "</td><td>" + name + "</td><td>" + email + "</td><td>"
					+ joinDate + "</td><td>" + "<a href='/pro08/member3?command=delMember&id=" + id
					+ "'>삭제 </a></td></tr>");

		}
		out.print("</table></body></html>");
		out.print("<a href='/pro08/memberForm.html'>새 회원 등록하기</a");
	}
}

 

4. http://localhost:8090/pro08/member로 요청하여 실행 결과를 확인합니다.

실행 결과

 

ViewServlet 클래스는 웹 브라우저에서 화면 기능을 담당하는데 이러한 기능을 하는 서블릿이 분화되어 발견이 바로 JSP입니다.