본문 바로가기

JSP&Servlet

회원가입 및 로그인

zipcode.txt
2.86MB

이번 포스팅에서는 지금까지 배웠던 것을 토대로 회원 인증 및 가입 프로그램을 구현해 보도록 하겠다. 회원 인증을 통해서 회원만의 특별한 기능을 제공하고 회원가입은 ID 중복체크, 우편번호 검색 등의 기능 구현을 통해서 JSP의 기본 Scripting Element와 JDBC 기술 그리고 세션의 의미를 명확히 하는 데 더욱 친숙해지는 기회가 될 수 있을 것이다.

 

1. 데이터베이스 설계

먼저 프로그래밍에 앞서 필요한 테이블을 만들어 보겠다. 총 2개의 테이블이 필요한데, 첫 번째는 회원들의 정보가 저장이 되는 회원테이블이고 두 번째는 전국의 우편번호와 주소가 저장되어 있는 우편번호 테이블이다.

 

 

우편번호는 데이터가 많으므로 해당 파일을 첨부파일에 올려놓겠다. 파일에 들어가서 복사하고 붙여넣기 하면 된다.

 

2. 설계 및 구현

1) 회원가입 만들기

 

[member.jsp]

<%@ page contentType="text/html; charset=EUC-KR" %>
<html>
<head>
<title>회원가입</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript">
	function idCheck(id) {
		// regFrm 이라는 html 코드를 가져옴
		frm = document.regFrm;
		// 아이디가 비워져 있는지 검사
		if (id == "") {
			alert("아이디를 입력해 주세요.");
			frm.id.focus();
			return;
		}
		//비워져 있지 않으면 주소를 만듦
		url = "idCheck.jsp?id=" + id;
		// 창을 위의 주소로 엶
		window.open(url, "IDCheck", "width=300,height=150");
	}
	// zipSearch()는 [우편번호찾기] 버튼을 클릭하면 호출되는 함수
	// 버튼 클릭 시, 우편번호검색(zipSearch.jsp) 페이지의 새로운 창이 만들어지면서
	// y라는 check 값을 가지고 넘어감 
	function zipSearch() {
		url = "zipSearch.jsp?search=n";
		window.open(url, "ZipCodeSearch","width=500,height=300,scrollbars=yes");
	}
</script>
</head>
<!-- 창이 열리면 아이디 입력 부분에 포커스가 됨 -->
<body bgcolor="#FFFFCC" onLoad="regFrm.id.focus()">
	<div align="center">
		<br /><br />
		<form name="regFrm" method="post" action="memberProc.jsp">
			<table cellpadding="5">
				<tr>
					<td bgcolor="#FFFFCC">
						<table border="1" cellspacing="0" cellpadding="2" width="600">
							<tr bgcolor="#996600">
								<td colspan="3"><font color="#FFFFFF"><b>회원 가입</b></font></td>
							</tr>
							<tr>
								<td width="20%">아이디</td>
								<td width="50%">
									<input name="id" size="15">
									<!-- 아이디 입력 후 [ID중복확인] 버튼을 클릭하면 idCheck() 함수가 호출되면서
									ID중복검색 창(idCheck.jsp)이 하나 뜬다. ID중복검색 창에서는 폼에서 입력한 ID와 
									회원테이블의 ID를 중복체크한다. --> 
									<input type="button" value="ID중복확인" onClick="idCheck(this.form.id.value)">
								</td>
								<td width="30%">아이디를 적어 주세요.</td>
							</tr>
							<tr>
								<td>패스워드</td>
								<td><input type="password" name="pwd" size="15"></td>
								<td>패스워드를 적어주세요.</td>
							</tr>
							<tr>
								<td>패스워드 확인</td>
								<td><input type="password" name="repwd" size="15"></td>
								<td>패스워드를 확인합니다.</td>
							</tr>
							<tr>
								<td>이름</td>
								<td><input name="name" size="15">
								</td>
								<td>이름을 적어주세요.</td>
							</tr>
							<tr>
								<td>성별</td>
								<td>
									남<input type="radio" name="gender" value="1" checked> 
									여<input type="radio" name="gender" value="2">
								</td>
								<td>성별을 선택 하세요.</td>
							</tr>
							<tr>
								<td>생년월일</td>
								<td><input name="birthday" size="6">
									ex)830815</td>
								<td>생년월일를 적어 주세요.</td>
							</tr>
							<tr>
								<td>Email</td>
								<td><input name="email" size="30">
								</td>
								<td>이메일를 적어 주세요.</td>
							</tr>
							<tr>
								<td>우편번호</td>
								<td><input name="zipcode" size="5" readonly>
								<!-- [우편번호찾기] 버튼을 클릭하면 zipCheck() 함수가 호출되면서 우편검색 창(zipSearch.jsp)이 뜬다.
								우편검색 창에서는 도로 명으로 우편번호와 주소를 검색하고 검색한 결괏값을 클릭하면 다시 회원가입 폼으로 
								우편번호와 주소가 자동으로 입력된다.-->
									<input type="button" value="우편번호찾기" onClick="zipSearch()">
								</td>
								<td>우편번호를 검색하세요.</td>
							</tr>
							<tr>
								<td>주소</td>
								<td><input name="address" size="45"></td>
								<td>주소를 적어 주세요.</td>
							</tr>
							<tr>
								<td>취미</td>
								<td>인터넷<input type="checkbox" name="hobby" value="인터넷">
									여행<input type="checkbox" name="hobby" value="여행"> 게임<input
									type="checkbox" name="hobby" value="게임"> 영화<input
									type="checkbox" name="hobby" value="영화"> 운동<input
									type="checkbox" name="hobby" value="운동">
								</td>
								<td>취미를 선택 하세요.</td>
							</tr>
							<tr>
								<td>직업</td>
								<td><select name=job>
										<option value="0" selected>선택하세요.
										<option value="회사원">회사원
										<option value="연구전문직">연구전문직
										<option value="교수학생">교수학생
										<option value="일반자영업">일반자영업
										<option value="공무원">공무원
										<option value="의료인">의료인
										<option value="법조인">법조인
										<option value="종교,언론,에술인">종교.언론/예술인
										<option value="농,축,수산,광업인">농/축/수산/광업인
										<option value="주부">주부
										<option value="무직">무직
										<option value="기타">기타
								</select></td>
								<td>직업을 선택 하세요.</td>
							</tr>
							<tr>
								<td colspan="3" align="center">
								   <input type="button" value="회원가입" onclick="inputCheck()">
								    &nbsp; &nbsp; 
								    <input type="reset" value="다시쓰기">
								    &nbsp; &nbsp;
								    <!-- [회원가입] 클릭하면 inputCheck() 함수가 호출되면서 회원가입 폼에 입력한 값들과 함께
								    memberProc.jsp 페이지로 이동한다. --> 
								    <input type="button" value="로그인" onClick="javascript:location.href='login.jsp'">
								 </td>
							</tr>
						</table>
					</td>
				</tr>
			</table>
		</form>
	</div>
</body>
</html>

 

[idCheck.jsp]

<%@ page contentType="text/html; charset=EUC-KR" %>
<!-- useBean 액션 태그로 MemberMgr 객체를 생성하고 있다. 그리고 생성한 객체를 가리키고 있는
변수, 즉 레퍼런스 변수는 mMgr이다. -->
<jsp:useBean id="mMgr" class="RegPack.MemberMgr" />
<%
	request.setCharacterEncoding("EUC-KR");
	String id = request.getParameter("id");
	// 중복 여부 체크
	// 중복 값이 있다면 check 변수의 값이 true로 반환되며, 중복이 없으면 false로 반환됨
	boolean result = mMgr.checkId(id);
%>
<html>
<head>
<title>ID 중복체크</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="#FFFFCC">
	<div align="center">
		<br/><b><%=id%></b>
		<%
		// if문을 이용해서 check 변수가 반환되는 값에 따라서 실행되는 내용을 다르게 출력하고 있다.
			if (result) {
				out.println("는 이미 존재하는 ID입니다.<p/>");
			} else {
				out.println("는 사용 가능합니다.<p/>");
			}
		%>
		<!-- 현재의 창이 닫히는 역할을 하는 스크립트 함수 -->
		<a href="#" onClick="self.close()">닫기</a>
	</div>
</body>
</html>

 

[zipSearch.jsp]

<%@ page contentType="text/html; charset=EUC-KR"%>
<!-- 클래스 정보 가져오기 -->
<%@page import="RegPack.ZipcodeBean"%>
<%@page import="java.util.Vector"%>
<!-- 클래스 객체 생성 -->
<jsp:useBean id="mMgr" class="RegPack.MemberMgr" />
<%
	request.setCharacterEncoding("EUC-KR");
	// 아래의 String 변수들은 [검색] 버튼 클릭 후에 요청한 search 값과 area3 값을 받는 변수들임
	String search = request.getParameter("search");
	 String area3 = null;
	 Vector<ZipcodeBean> vlist = null;
	 if (search.equals("y")) {
		 // 요청한 area3 값의 매개변수로 MemberMgr 클래스의 zipcodeRead() 메소드를 호출하여
		 // 반한되는 값을 Vector 타입의 vlist로 반환 받는다.
		area3 = request.getParameter("area3");
		vlist = mMgr.zipcodeRead(area3);
	 }
%>
<html>
<head>
<title>우편번호 검색</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript">
	// 자바스크립트 loadSearch() 함수는 입력된 도로명 값을 가지고 자신의 페이지(zipSearch.jsp)를 호출한다.
	// form문에서는 넘어가고자 하는 페이지, 즉 action 값을 지정하지 않으면 자신의 페이지를 호출하지만 여기서는
	// 명시적으로 zipSearch.jsp로 지정하였다.
	function loadSearch() {
		frm = document.zipFrm;
		if (frm.area3.value == "") {
			alert("도로명을 입력하세요.");
			frm.area3.focus();
			return;
		}
		frm.action = "zipSearch.jsp"
		frm.submit();
	}

	// sendAdd() 함수는 도로명으로 검색된 우편번호와 주소의 값들을 가지고 자신을 오픈시킨 페이지(member.jsp)로
	// 넘어가면서 창을 닫는 자바스크립트 함수이다.
	function sendAdd(zipcode, adds) {
		opener.document.regFrm.zipcode.value = zipcode;
		opener.document.regFrm.address.value = adds;
		self.close();
	}
</script>
</head>
<body bgcolor="#FFFFCC">
	<div align="center">
		<br />
		<form name="zipFrm" method="post">
			<table>
				<tr>
					<td><br/>도로명 입력 : <input name="area3">
					 <input type="button" value="검색" onclick="loadSearch();">
					 </td>
				</tr>
				<!-- 검색결과 시작 -->
				<%
				// 검색란에 도로명을 입력하고 검색을 클릭하면 hidden 타입의 search 값이 y로 넘어오면서
				// 67라인부터의 내용들을 출력한다. 만약 조건에 맞는 우편번호와 주소가 없다면 67라인의 내용이
				// 출력되고 검색된 내용들이 있다면 73라인 이하부터 출력이 된다.
					if (search.equals("y")) {
							if (vlist.isEmpty()) {
				%>
				<tr>
					<td align="center"><br/>검색된 결과가 없습니다.</td>
				</tr>
				<%
					} else {
				%>
				<tr>
					<td align="center"><br/>※검색 후, 아래 우편번호를 클릭하면 자동으로 입력됩니다.</td>
				</tr>
				<%
				// 17라인의 결괏값을 Vector의 크기만큼 for문 루프를 돌려서 우편번호와 주소의 결괏값을 
				// ZipcodeBean 타입으로 반환하고 있다. 참고로, Vector의 반환 타입은 Object이지만
				// zipcodeRead() 메소드의 변환 타입은 Vector<ZipcodeBean> 타입으로 제네릭 선언을
				// 했기 때문에 변환없이 바로 ZipcodeBean 타입으로 반환을 받는다.
					for (int i = 0; i < vlist.size(); i++) {
							ZipcodeBean bean = vlist.get(i);
							// ZipcodeBean 객체가 가지고 있는 변수의 값들을 getXxx() 메소드를 호출하면서 각각의 값들을
							// String 객체로 반환하였다. area1, area2, area3의 주소 값을 adds String 변수로 선언한다.
							String rZipcode = bean.getZipcode();
							String rArea1 = bean.getArea1();
							String rArea2 = bean.getArea2();
							String rArea3 = bean.getArea3();
							String adds = rArea1 + " " + rArea2 + " " + rArea3 + " ";
				%>
				<tr>
					<!-- 검색한 결과의 우편번호와 주소를 표현식으로 페이지(zipSearch.jsp)에 출력을 하고 
					출력된 주소 값을 자바스크립트 sendAdd() 함수를 호출하여 우편번호와 주소를 member.jsp 페이지의
					우편번호 란과 주소 란에 자동으로 입력한다. 입력된 후에는 zipSearch.jsp는 페이지가 자동으로 닫힌다. -->
					<td><a href="#"
						onclick="javascript:sendAdd('<%=rZipcode%>','<%=adds%>')">
							<%=rZipcode%> <%=adds%></a></td>
				</tr>
				<%
					}//for
						}//if
					}//if
				%>
				<!-- 검색결과 끝 -->
				<tr>
					<td align="center"><br/>
					<a href="#" onClick="self.close()">닫기</a></td>
				</tr>
			</table>
			<input type="hidden" name="search" value="y">
		</form>
	</div>
</body>
</html>

 

[memberProc.jsp]

<%@page contentType="text/html; charset=EUC-KR" %>
<%request.setCharacterEncoding("EUC-KR");%>
<!-- 회원가입을 위한 insertMember() 메소드(8라인)를 사용하기 위해서 MemberMgr 객체를 생성 -->
<jsp:useBean id="mgr" class="RegPack.MemberMgr"/>

<!-- member.jsp에서 작성한 회원가입 내용들을 bean 변수가 가리키고 있는 MemberBean 객체를 생성하고
'<jsp:setProperty>' 액션을 통해서 setXxx 메소드를 호출하여 MemberBean 객체가 가지고 있는
private 변수에 입력한 값들을 세팅(저장)한다. -->
<jsp:useBean id="bean" class="RegPack.MemberBean"/>
<jsp:setProperty property="*" name="bean"/>
<%
		// MemberBean 타입의 매개벼수로 MemberMgr.java 클래스의 insertMember() 메소드를 호출하여
		// 반환되는 boolean 타입의 값을 result 변수로 받는다. 입력이 성공적으로 되었다면 result 값은 true를
		// 반환시키지만 여러 가지 이유에 의해서 입력이 되지 않았다면 false 값으로 반환된다.
		boolean result = mgr.insertMember(bean);

		// boolean 타입의 result 값이 true이면 회원가입 축하 메시지와 로그인 페이지(login.jsp) 화면으로
		// 전환되지만 result 값이 false이면 재가입 입력 메시지와 회원가입 페이지(member.jsp) 화면으로 전환된다.
		String msg = "회원가입에 실패 하였습니다.";
		String location = "member.jsp";
		if(result){
			msg = "회원가입을 하였습니다.";
			location = "login.jsp";
		}
%>
<script>
	alert("<%=msg%>");
	location.href = "<%=location%>";
</script>

 

[script.js]

function inputCheck(){
	if(document.regFrm.id.value==""){
		alert("아이디를 입력해 주세요.");
		document.regFrm.id.focus();
		return;
	}
	if(document.regFrm.pwd.value==""){
		alert("비밀번호를 입력해 주세요.");
		document.regFrm.pwd.focus();
		return;
	}
	if(document.regFrm.repwd.value==""){
		alert("비밀번호를 확인해 주세요");
		document.regFrm.repwd.focus();
		return;
	}
	// 입력한 비밀번호와 확인 비밀번호가 맞지 않으면 경고 메시지가 출력됨
	if(document.regFrm.pwd.value != document.regFrm.repwd.value){
		alert("비밀번호가 일치하지 않습니다.");
		document.regFrm.repwd.value="";
		document.regFrm.repwd.focus();
		return;
	}
	if(document.regFrm.name.value==""){
		alert("이름을 입력해 주세요.");
		document.regFrm.name.focus();
		return;
	}
	if(document.regFrm.birthday.value==""){
		alert("생년월일을 입력해 주세요.");
		document.regFrm.birthday.focus();
		return;
	}
	if(document.regFrm.email.value==""){
		alert("이메일을 입력해 주세요.");
		document.regFrm.email.focus();
		return;
	}
	
	// 이메일 형식을 검사하는 부분
    var str=document.regFrm.email.value;	   
    var atPos = str.indexOf('@'); // 제일 처음에 나오는 @ 위치
    var atLastPos = str.lastIndexOf('@'); // 제일 마지막에 나오는 @ 위치
    var dotPos = str.indexOf('.'); 
    var spacePos = str.indexOf(' ');
    var commaPos = str.indexOf(',');
    var eMailSize = str.length;
    
    // 이메일 양식 검사
    if (atPos > 1 // @ 앞에 글자가 2개 이상
     	&& atPos == atLastPos // @가 하나만 있는지 검사
    	&& dotPos > 3 // . 앞의 글자가 4개 이상
    	&& spacePos == -1 // 공백 없음 검사
    	&& commaPos == -1 // 콤마 없음 검사
	    && atPos + 1 < dotPos // @와 . 사이에 최소 글자가 1개 이상
	    && dotPos + 1 < eMailSize); // . 뒤에 글자가 1개 이상
    else {
          alert('E-mail주소 형식이 잘못되었습니다.\n\r다시 입력해 주세요!');
	      document.regFrm.email.focus();
		  return;
    }
    if(document.regFrm.zipcode.value==""){
		alert("우편번호를 검색해 주세요.");
		return;
	}
	if(document.regFrm.job.value=="0"){
		alert("직업을 선택해 주세요.");
		document.regFrm.job.focus();
		return;
	}
	document.regFrm.submit();
}

function win_close(){
	self.close();
}

 

2) 회원인증 만들기

[login.jsp]

<%@ page contentType="text/html; charset=EUC-KR" %>
<%
	  request.setCharacterEncoding("EUC-KR");
	  // 세션에 저장되어 있는 'idKey' 키 값을 반환한다. 로그인을 하지 않았다면 null 값이 반환되지만
	  // 만약 로그인이 되어 있다면 id 값이 'idKey' 키 값으로 세선에 저장되어 있다.
	  String id = (String)session.getAttribute("idKey");
%>
<html>
<head>
<title>로그인</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript">
	function loginCheck() {
		if (document.loginFrm.id.value == "") {
			alert("아이디를 입력해 주세요.");
			document.loginFrm.id.focus();
			return;
		}
		if (document.loginFrm.pwd.value == "") {
			alert("비밀번호를 입력해 주세요.");
			document.loginFrm.pwd.focus();
			return;
		}
		document.loginFrm.submit();
	}
</script>
</head>
<body bgcolor="#ffffcc">
<div align="center"><br/><br/>
<!-- 세선에 저장되어 있는 'idKey' 키 값이 null이 아니면 로그인 후에는 if문 블록이 실행되면서 제한적인 기능들의
사용이 가능할 수 있도록 표현되지만 로그인이 되어 있지 않으면 'idKey' 키 값이 null이므로 else문 이하의 블록이
실행되면서 로그인 입력 폼이 실행된다. -->
		<%if (id != null) {%>
		<b><%=id%></b>님 환영 합니다.
		<p>제한된 기능을 사용 할 수가 있습니다.<p/>
			<a href="logout.jsp">로그아웃</a>
			<%} else {%>
			
		<!-- 아이디와 비밀번호 입력 후에 로그인 버튼을 클릭하면 입력한 값들과 함꼐 loginProc.jsp로 이동한다.
		[회원가입] 버튼을 클릭하면 member.jsp로 이동한다. -->
		<form name="loginFrm" method="post" action="loginProc.jsp">
			<table>
				<tr>
					<td align="center" colspan="2"><h4>로그인</h4></td>
				</tr>
				<tr>
					<td>아 이 디</td>
					<td><input name="id"></td>
				</tr>
				<tr>
					<td>비밀번호</td>
					<td><input type="password" name="pwd"></td>
				</tr>
				<tr>
					<td colspan="2">
						<div align="right">
							<input type="button" value="로그인" onclick="loginCheck()">&nbsp;
							<input type="button" value="회원가입" onClick="javascript:location.href='member.jsp'">
						</div>
					</td>
				</tr>
			</table>
		</form>
		<%}%>
	</div>
</body>
</html>

 

[loginProc.jsp]

<%@ page contentType="text/html; charset=EUC-KR" %>
<jsp:useBean id="mMgr" class="RegPack.MemberMgr"/>
<%
	  request.setCharacterEncoding("EUC-KR");

	// login.jsp에서 입력받은 아이디와 비밀번호인 id와 pwd를 각각 String 객체로 반환한다.
	  String id = request.getParameter("id");
	  String pwd = request.getParameter("pwd");
	  String url = "login.jsp";
	  String msg = "로그인에 실패 하였습니다.";
	  
	// id와 pwd의 매개변수로 loginMember() 메소드를 호출한다. loginMember() 메소드의 반환 값
	// boolean 타입의 result 변수이다. result 변수의 반환되는 값이 true이면 아이디와 비밀번호가
	// 일치되어 로그인에 성공하지만 아이디와 비밀번호가 일치하지 않으면 false 값을 반환하여 로그인에 성공 X
	  boolean result = mMgr.loginMember(id,pwd);
	  if(result){
		  // 로그인 상태 유지를 위해 세션 설정
		  // 로그인에 loginMember() 변수 값이 true이면 세션 객체의 setAttribute() 메소드를 호출하여
		  // id 값을 idKey라는 key 값으로 저장한다. 그리고 msg 변수에 '로그인에 성공하였습니다.' 문자열 선언함
	    session.setAttribute("idKey",id);
	    msg = "로그인에 성공 하였습니다.";
	  }
%>
<script>
	alert("<%=msg%>");	
	location.href="<%=url%>";
</script>

 

[logout.jsp]

<%@ page contentType="text/html; charset=EUC-KR"%>
<%
	// session.invalidate() 메소드는 현재의 세선에 저장되어 있는 데이터를 완전히 삭제를 한 후에
	// 자바스크립트로 '로그아웃 되었습니다.' 라고 메시지를 띄우고 login.jsp 페이지로 이동한다.
      session.invalidate();
%>
<script>
   alert('로그아웃 되었습니다.');
   location.href="login.jsp";
</script>

 

3) 회원 인증 및 가입에 필요한 자바와 빈즈 만들기

[MemberBean.java]

package RegPack;

public class MemberBean {

	private String id;			// 회원 ID를 저장할 변수
	private String pwd;			// 회원 비밀번호를 저장할 변수
	private String name;		// 회원 이름을 저장할 변수
	private String gender;		// 회원 성별을 저장할 변수
	private String birthday;	// 회원 생년월일을 저장할 변수
	private String email;		// 회원 이메일 저장할 변수
	private String zipcode;		// 회원 우편번호를 저장할 변수
	private String address;		// 회원 주소를 저장할 변수
	private String hobby[];		// 회원 취미를 저장할 변수
	private String job;			// 회원 직업을 저장할 변수

	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 getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getEmail() {
		return email;
	}

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

	public String getZipcode() {
		return zipcode;
	}

	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}
	// 다른 변수들과 다르게 반환형이 String 배열이다.
	public String[] getHobby() {
		return hobby;
	}
	// String 배열을 인자 값으로 받는다.
	public void setHobby(String[] hobby) {
		this.hobby = hobby;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}	
}

 

[ZipcodeBean.java]

package RegPack;

public class ZipcodeBean {

	private String zipcode;		// 우편번호를 저장할 변수
	private String area1;		// 도시 또는 도를 저장할 변수
	private String area2;		// 구 또는 소도시를 저장할 변수
	private String area3;		// 도로 명을 저장할 변수

	public String getZipcode() {
		return zipcode;
	}

	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	public String getArea1() {
		return area1;
	}

	public void setArea1(String area1) {
		this.area1 = area1;
	}

	public String getArea2() {
		return area2;
	}

	public void setArea2(String area2) {
		this.area2 = area2;
	}

	public String getArea3() {
		return area3;
	}

	public void setArea3(String area3) {
		this.area3 = area3;
	}
}

 

[MemberMgr.java]

package RegPack;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Vector;

public class MemberMgr {

	private DBConnectionMgr pool;

	// 생성자(Constructor)
	// 반환형이 없고, 클래스명과 같은 이름의 함수
	public MemberMgr() {
		try {
			// MemberMgr 생성자 내부에 DBConnectionMgr 클래스의 객체 생성을 위해서 getInstance() 
			// 메소드를 호출하였다. MemberMgr 객체를 생성하면 DBConnectionMgr 객체가 생성되면서 
			// 10라인에 선언한 DBConnectionMgr 객체 변수로 반환한다.
			pool = DBConnectionMgr.getInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// ID 중복확인
	public boolean checkId(String id) {
		Connection con = null;
		// 쿼리문을 실행시켜줌
		PreparedStatement pstmt = null;
		// 헤당 결과를 받아옴
		ResultSet rs = null;
		// 실행 쿼리문을 담을 변수 지정
		String sql = null;
		boolean flag = false;
		try {
			// DBConnectionMgr pool 객체를 통해서 Mysql에 연결함
			con = pool.getConnection();
			sql = "select id from tblMember where id = ?";
			// 쿼리 동작시킬 준비가 됨(SQL문을 DB에 보내기 위함)
			pstmt = con.prepareStatement(sql);
			// 첫 번째 ?인 곳에 id를 넣음
			pstmt.setString(1, id);
			// id 열에 찾고자 하는 결괏값이 있는지 검사하면서 가져옴
			flag = pstmt.executeQuery().next();
		} catch (Exception e) {
			// 예외가 발생하면 예외 내용을 String 형식으로 출력함
			e.printStackTrace();
		} finally {
			// Connection 객체를 재사용하기 위해서 닫지 않고 pool에 반납함
			pool.freeConnection(con, pstmt, rs);
		}
		return flag;
	}

	// 우편번호 검색
	// zipcodeRead() 메소드의 역할은 회원가입 폼(member.jsp)에서 우편번호를 검색하기 위해
	// [우편번호 찾기] 버튼을 클릭하면 zipSearch.jsp 페이지 창이 뜬다. 이 페이지에서 우편번호와
	// 주소 검색을 위해 입력받은 도로명을 매개변수로 우편번호 테이블에서 검색한 결괏값을 ZipcodeBean로 받은 후에
	// 하나 또는 여러 개의 빈즈들을 Vector에 담은 후에 이 Vector를 반환하는 메소드이다.
	public Vector<ZipcodeBean> zipcodeRead(String area3) {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = null;
		// 벡터에 동적으로 할당하기 위한 준비
		Vector<ZipcodeBean> vlist = new Vector<ZipcodeBean>();
		try {
			con = pool.getConnection();
			// area3가 들어있는 비슷한 것들을 다 찾아라
			sql = "select * from tblZipcode where area3 like ?";
			pstmt = con.prepareStatement(sql);
			// 첫 번쨰 빈칸에 area3를 넣음 -> area3가 끼어있는 문자열을 찾음
			// ex) 앞뒤 상관없이 강남대로라는 글자가 들어있는 데이터를 찾음
			pstmt.setString(1, "%" + area3 + "%");
			rs = pstmt.executeQuery();
			while (rs.next()) {
				ZipcodeBean bean = new ZipcodeBean();
				// SQL문 결괏값을 bean에 저장함
				// 데이터베이스는 다 문자열이기 때문에 int나 다른 형으로 바꾸고 싶으면 해당 type으로 바꿔줘야 함
				// ex) int val = Integer.parseInt(rs.getString(1));
				bean.setZipcode(rs.getString(1));
				bean.setArea1(rs.getString(2));
				bean.setArea2(rs.getString(3));
				bean.setArea3(rs.getString(4));
				// 해당 결과들을 벡터에다가 하나씩 넣음
				vlist.addElement(bean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			pool.freeConnection(con, pstmt, rs);
		}
		// 조회 끝나면 벡터의 주소들을 반환함
		return vlist;
	}

	// 회원가입
	// insertMember() 메소드의 매개변수는 MemberBean 객체이고 반환형은 boolean 타입이다.
	// insertMember() 메소드의 역할은 회원가입 폼(member.jsp)에서 입력받은 회원가입 내용들을
	// memberProc.jsp 페이지에서 MemberBean 객체에 저장한 후 MemberBean 매개변수로 회원테이블에 저장한다.
	// 만약 여러 이유로 입력되지 않았다면 false 값을 반환하고, 입력이 정상적으로 처리가 되었다면 true 값을 반환함
	public boolean insertMember(MemberBean bean) {
		Connection con = null;
		PreparedStatement pstmt = null;
		String sql = null;
		boolean flag = false;
		try {
			con = pool.getConnection();
			// 회원정보를 데이터베이스에 삽입하기 위한 쿼리문
			// NOT NULL인 곳에는 무조건 값을 넣어줘야 함(생략 X)
			sql = "insert tblMember(id,pwd,name,gender,birthday,email,zipcode"
					+ ",address,hobby,job)values(?,?,?,?,?,?,?,?,?,?)";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, bean.getId());
			pstmt.setString(2, bean.getPwd());
			pstmt.setString(3, bean.getName());
			pstmt.setString(4, bean.getGender());
			pstmt.setString(5, bean.getBirthday());
			pstmt.setString(6, bean.getEmail());
			pstmt.setString(7, bean.getZipcode());
			pstmt.setString(8, bean.getAddress());
			
			// BitFlag 형식으로 하면 좀 더 효율적으로 기능함
//			String hobby[] = bean.getHobby();
//			char hobbyFlag = 0;
//			for( int i = 0; i < hobby.length; ++i) {
//				hobbyFlag |= hobby[i];
//			}

			// 취미를 가져옴
			// ex) ["게임", "영화", "운동"]
			String hobby[] = bean.getHobby();
			// DB에 저장할 hb 배열을 0으로 초기화함
			char hb[] = { '0', '0', '0', '0', '0' };
			// String 배열 lists에 취미 5개를 배열로 선언함
			String lists[] = { "인터넷", "여행", "게임", "영화", "운동" };
			// 본인이 체크한 취미의 개수만큼 반복문 돌림
			for (int i = 0; i < hobby.length; i++) {
				// j는 전체 취미 목록만큼 반복문 돌림
				for (int j = 0; j < lists.length; j++) {
					if (hobby[i].equals(lists[j]))
						// SQL 결괏값이 저장된 hobby[] 배열의 값과 list[] 배열의 값이 같은지 비교함
						// 같으면 체크가 된 것이므로 처음 '0'으로 초기화된 hb[] 배열의 hb[j] 값을
						// '1'로 저장함
						// 결과적으로 '게임 영화 운동'을 체크했다면 '00111'로 DB에 저장이 됨
						hb[j] = '1';
				}
			}
			
			pstmt.setString(9, new String(hb));
			pstmt.setString(10, bean.getJob());
			if (pstmt.executeUpdate() == 1)
				flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			pool.freeConnection(con, pstmt);
		}
		return flag;
	}

	// 로그인
	// loginMember() 메소드의 매개변수는 String 객체가 두 개이며, 반환형은 boolean 타입이다.
	// loginMember() 메소드의 역할은 login.jsp에서 입력받은 아이디와 비밀번호를 매개변수로,
	// 회원테이블에서 검색 후에 아이디와 비밀번호가 일치하면서 true 값을 반환하고 일치하지 않으면 false 값 반환함
	public boolean loginMember(String id, String pwd) {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = null;
		boolean flag = false;
		try {
			con = pool.getConnection();
			sql = "select id from tblMember where id = ? and pwd = ?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, id);
			pstmt.setString(2, pwd);
			rs = pstmt.executeQuery();
			flag = rs.next();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			pool.freeConnection(con, pstmt, rs);
		}
		return flag;
	}
	
	/*************
	 * 아래의 코드들은 추후에 필요한 메소드임
	 * ************/

	// 회원정보가져오기
	public MemberBean getMember(String id) {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		MemberBean bean = null;
		try {
			con = pool.getConnection();
			String sql = "select * from tblMember where id = ?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				bean = new MemberBean();
				bean.setId(rs.getString("id"));
				bean.setPwd(rs.getString("pwd"));
				bean.setName(rs.getString("name"));
				bean.setGender(rs.getString("gender"));
				bean.setBirthday(rs.getString("birthday"));
				bean.setEmail(rs.getString("email"));
				bean.setZipcode(rs.getString("zipcode"));
				bean.setAddress(rs.getString("address"));
				String hobbys[] = new String[5];
				String hobby = rs.getString("hobby");// 01001
				for (int i = 0; i < hobbys.length; i++) {
					hobbys[i] = hobby.substring(i, i + 1);
				}
				bean.setHobby(hobbys);
				bean.setJob(rs.getString("job"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			pool.freeConnection(con);
		}
		return bean;
	}

	// 회원정보수정
	public boolean updateMember(MemberBean bean) {
		Connection con = null;
		PreparedStatement pstmt = null;
		boolean flag = false;
		try {
			con = pool.getConnection();
			String sql = "update tblMember set pwd=?, name=?, gender=?, birthday=?,"
					+ "email=?, zipcode=?, address=?, hobby=?, job=? where id = ?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, bean.getPwd());
			pstmt.setString(2, bean.getName());
			pstmt.setString(3, bean.getGender());
			pstmt.setString(4, bean.getBirthday());
			pstmt.setString(5, bean.getEmail());
			pstmt.setString(6, bean.getZipcode());
			pstmt.setString(7, bean.getAddress());
			char hobby[] = { '0', '0', '0', '0', '0' };
			if (bean.getHobby() != null) {
				String hobbys[] = bean.getHobby();
				String list[] = { "인터넷", "여행", "게임", "영화", "운동" };
				for (int i = 0; i < hobbys.length; i++) {
					for (int j = 0; j < list.length; j++)
						if (hobbys[i].equals(list[j]))
							hobby[j] = '1';
				}
			}
			pstmt.setString(8, new String(hobby));
			pstmt.setString(9, bean.getJob());
			pstmt.setString(10, bean.getId());
			int count = pstmt.executeUpdate();
			if (count > 0)
				flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			pool.freeConnection(con, pstmt);
		}
		return flag;
	}
}

 

[결과]

 

 

-- Member.jsp의 [중복확인] 버튼 결과 --

 

-- Member.jsp의 [우편번호찾기] 버튼 결과 --

 

-- Member.jsp의 [회원가입] 버튼 결과 --

 

-- 회원가입 완료 및 로그인 --

 

-- 로그아웃 버튼 결과 --

'JSP&Servlet' 카테고리의 다른 글

계층형 게시판(2)  (0) 2022.04.05
계층형 게시판(1)  (0) 2022.04.04
세션(Session)과 쿠키(Cookie)_추가 내용  (0) 2022.03.22
세션(Session)과 쿠키(Cookie)  (0) 2022.03.21
JDBC로 데이터베이스 연동  (0) 2022.03.18