본문 바로가기
Java Web Programming/4. JSP

[JSP/세션관리] 2단계_Cookie 쿠키 & Session 세션을 이용한 회원정보 수정 및 회원가입 프로그램 구현 (+아이디 중복 확인)

by 파프리카_ 2020. 9. 4.
728x90
반응형

이 포스팅은 '로그인 유지 프로그램' 포스팅과 이어지는 포스팅입니다.

기능은 '회원 정보 수정' 과 '회원 가입' 기능이 추가됩니다 !

https://creamilk88.tistory.com/103 을 참고하여 이어지는 포스팅으로 참고해주세요!

 

[JSP/세션관리] 1단계_Cookie 쿠키 & Session 세션을 이용한 로그인 유지 프로그램 구현

[ 진행 과정(흐름) ]  WAS (Web Container) client(browser) ---> request -----> if (모델과 연동해 아이디 패스워드 일치하면)      HttpSession session = request.getSession( );  : 위 코드는 세션이..

creamilk88.tistory.com


[ 잠깐 Review ! ]

* Cookie와 HttpSession

→ HTTP : Stateless (상태 정보 유지 X)

    ⇒ 상태 정보 유지 방법 !

         ① Cookie - 클라이언트 측에 저장 : 용량, 타입 제한 O

② Session - 서버 측에 저장 : 용량, 타입 제한 X

 

* JSP 내장 객체

  request  session  Application (ServletContext)
유효범위 response 될 때 까지 일정 조건 (session - timeout) 웹 어플리케이션 종료까지
  setAttribute(name, value)
getAtrribute(name)

 


[ 프로그램 진행 원리 및 개요 ]

Model2 설계방식 ( + MVC / Singleton / Front Controller Pattern 적용)

 

4번 기능 :  회원 정보 수정

 

5+6번 기능 : 회원 가입 (+아이디 중복 체크) 기능


[ 전체 구현 코드 ] 

DB Table

 

Model

/MemberVO.java

https://creamilk88.tistory.com/103 에서 제공하는 코드와 동일합니다. 

 

/ProductDAO.java

findMemberById(), login() method는 앞 포스팅에서 활용한 1,2 번 기능을 구현하기 위한 method입니다.

나머지 method는 이번 포스팅에서 새로운 기능을 구현하기 위해 추가된 method입니다.

package org.kosta.model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MemberDAO {
	//singleton 적용
	private static MemberDAO instance = new MemberDAO();
	
	//JDBC에 필요한 변수
	private String driver = "oracle.jdbc.OracleDriver";
	private String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
	private String username = "scott";
	private String userpass = "tiger";

	//class 생성 단계에서 singleton으로 한번 생성 + driver loading
	//사실 driver loading은 현재 java version에서는 따로 기재해주지 않아도,
	//자동으로 loading된다 ! 
	private MemberDAO() {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	//getInstance() method : 생성자 객체 반환용
	public static MemberDAO getInstance() {
		return instance;
	}
	
	//closeAll method 1
	public void closeAll(PreparedStatement pstmt, Connection con) 
			throws SQLException {
		if (pstmt != null)
			pstmt.close();
		if (con != null)
			con.close();
	}
	
	//closeAll method 2
	public void closeAll(ResultSet rs, PreparedStatement pstmt, Connection con) 
			throws SQLException {
		if (rs != null)
			rs.close();
		//재사용
		this.closeAll(pstmt, con);
	}
	
	/*
	 * 1번 기능 : 아이디로 회원정보 조회
	 * findMemberById(String):MemberVO 
	 */
	public MemberVO findMemberById(String id) throws SQLException {
		MemberVO vo = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			con = DriverManager.getConnection(url, username, userpass);
			String sql = "SELECT name, address FROM web_member " 
					+ "WHERE id = ?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			if(rs.next()) {
				vo = new MemberVO(id, null, rs.getString(1),rs.getString(2));
			}
			
		} finally {
			closeAll(rs, pstmt, con);
		}
		
		return vo;
	}
	
	/*
	 * 2번 기능 : 로그인 기능
	 * login(MemberVO):MemberVO 
	 */
	public MemberVO login(MemberVO vo) throws SQLException {
		MemberVO mvo = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			con = DriverManager.getConnection(url, username, userpass);
			String sql = "SELECT name, password, address FROM web_member "
					+ "WHERE id=? AND password=?";
			pstmt = con.prepareStatement(sql);
			
			pstmt.setString(1, vo.getId());
			pstmt.setString(2, vo.getPassword());
			
			rs = pstmt.executeQuery();
			
			if(rs.next()){
				mvo = new MemberVO(vo.getId(), rs.getString("password"),
						rs.getString("name"),rs.getString("address"));
			}
		} finally {
			closeAll(rs, pstmt, con);
		}
		return mvo;
	}
	
	/*
	 * 4번 기능 : 회원 정보 수정 기능
	 * updateMember(MemberVO):void 
	 */
	public void  updateMember(MemberVO vo) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		
		try {
			con = DriverManager.getConnection(url, username, userpass);
			
			StringBuilder sql = new StringBuilder();
			sql.append("UPDATE web_member ");
			sql.append("SET password=?, name=?, address=? ");
			sql.append("WHERE id=?");
			
			pstmt = con.prepareStatement(sql.toString());
			//password
			pstmt.setString(1, vo.getPassword());
			//name
			pstmt.setString(2, vo.getName());
			//address
			pstmt.setString(3, vo.getAddress());
			//id
			pstmt.setString(4, vo.getId());
			
			pstmt.executeUpdate();
			
		} finally {
			closeAll(pstmt, con);
		}
	}
	
	/*
	 * 5번 기능 : 회원 가입 기능
	 * register(MemberVO):void 
	 */
	public void register(MemberVO vo) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		
		try {
			con = DriverManager.getConnection(url, username, userpass);
			
			StringBuilder sql = new StringBuilder();
			sql.append("INSERT INTO web_member(id, password, name, address) ");
			sql.append("VALUES (?, ?, ?, ?)");
			
			pstmt = con.prepareStatement(sql.toString());
			pstmt.setString(1, vo.getId());
			pstmt.setString(2, vo.getPassword());
			pstmt.setString(3, vo.getName());
			pstmt.setString(4, vo.getAddress());
			
			pstmt.executeUpdate();
			
		} finally {
			closeAll(pstmt, con);
		}
	}
	
	/*
	 * 6번 기능 : 아이디 중복 체크 기능
	 * idCheck(String id):boolean
	 */
	public boolean idCheck(String id) throws SQLException {
		boolean flag = false;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			con = DriverManager.getConnection(url, username, userpass);
			String sql = "SELECT COUNT(*) FROM web_member WHERE id=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			
			if(rs.next() && rs.getInt(1) > 0)  //중복 id가 있으면
				flag = true; //flag를 true로 변환
					
		} finally {
			closeAll(rs, pstmt, con);
		}
		return flag;
	}
}//class

 


View

/index.jsp

<%@page import="org.kosta.model.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
	<div class="container">
		<h4>
			<a href="index.jsp"><img class="home-image" src="home.png">Home</a>
		</h4>
		<hr>
		<h3>Model2 회원 관리</h3>
		<a href="findmemberbyid.jsp">회원 검색</a><br>
		<%
			//로그인 여부 확인 방법 
		//(session 유무 확인 + 로그인 시 할당한 attribute 존재 확인)

		HttpSession session = request.getSession(false);
		// (A && B) : A가 false이면 뒤에 B는 확인하지 않는다.
		if (session != null && session.getAttribute("mvo") != null) {
			MemberVO mvo = (MemberVO) session.getAttribute("mvo");
		%>
			<br><%=mvo.getAddress()%>에 사는
			<%=mvo.getName()%>님 로그인 상태<br> 
			<a href="front?command=logout">로그아웃</a><br>

			<%-- 회원정보 수정 기능 --%>
			<a href="update-form.jsp">회원정보 수정</a>

		<%
			} else {
		%>
			<a href="login.jsp">로그인 페이지로</a><br><br>
			<%-- 회원 가입 기능 --%>
			<a href="register-form.jsp">회원 가입하기</a>
		<%
			}
		%>

	</div>
</body>
</html>

 

/error.jsp

https://creamilk88.tistory.com/103 에서 제공하는 코드와 동일합니다. 


-- 4번 기능 : 회원 정보 수정 기능 

: 로그인에서 이용한 session을 그대로 유지하여 이용한다. (새로운 세션을 생성하지 않는다!)

 

/update-form.jsp

<%@page import="org.kosta.model.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>회원 정보 수정 form</title>
</head>
<body>
	<div class="container">
		<a href="index.jsp"><img class="home-image" src="home.png">Home</a>
		<hr>
		
		<%--
			 로그인 유무에 따라 다른 결과 값을 보여준다
			 로그인 여부 확인 후 회원 정보 수정 권한을 준다
		 --%>
		 
		<%
			//로그인한 사용자인지 확인 
			//(1.세션 유무와 2.세션 내의 인증정보 유무)
			HttpSession session = request.getSession(false);
			if (session != null && session.getAttribute("mvo") != null){
				MemberVO mvo = (MemberVO) session.getAttribute("mvo");
		%>
			<h4>회원 정보 수정</h4>
			<form action="front" method="POST">
				<input type="hidden" name="command" value="updateMember">
				<%-- readonly="readonly" : 수정을 불가능하게 하는 속성 --%>
				아이디 <input type="text" name="id" readonly="readonly" 
						value="<%=mvo.getId()%>"><br>	
				패스워드 <input type="password" name="password" 
							value="<%=mvo.getPassword()%>"><br>
				이름 <input type="text" name="name" 
						value="<%=mvo.getName()%>"><br>
				주소 <input type="text" name="address" 
						value="<%=mvo.getAddress()%>"><br>
				<input type="submit" value="수정하기"> 
			</form>
		<% } else { %>
			로그인 후 이용 가능한 서비스입니다.<br>
			로그인 해주세요!<br><br>
			<a href="login.jsp">로그인 페이지로</a>
		<% } %>
	</div>
</body>
</html>

 

/update-result.jsp

<%@page import="org.kosta.model.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>css test</title>
</head>
<body>
	<div class="container">
		<a href="index.jsp"><img class="home-image" src="home.png">Home</a>
		<hr>
		<h4> 회원정보가 성공적으로 수정 완료되었습니다.</h4><br>
		<% 
			/*새로 세션을 만들지 않고, login부터 이어져온 session을 사용한다.
			* -> UpdateMemberController에 의해 attribute정보가 새로 바뀐 정보를
			*    가져와서 활용한다. (session.getAttribute("mvo", mvo))
			*/
			HttpSession session = request.getSession(false);
		
			if (session != null && session.getAttribute("mvo")!=null) {
				MemberVO mvo = (MemberVO) session.getAttribute("mvo"); %>
				
				아이디 : <%=mvo.getId() %><br>
				패스워드 : <%=mvo.getPassword() %><br>
				이름 : <%=mvo.getName() %><br>
				주소 : <%=mvo.getAddress() %><br>
				
		<% } else { %>
				<script type="text/javascript">
					alert("로그인을 먼저 해주세요!");
					location.href = "login.jsp";
				</script>
			
		<% } %>	
		
	</div>
</body>
</html>

 

--  5번 기능 :  회원 가입 기능  (+ 아이디 중복체크 기능도 register-form.jsp에 포함됨)

                               

/register-form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>회원가입 form</title>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<script type="text/javascript">
	
	function CheckPassword() {
		//getting object
		var passwordObj = document.registerForm.password;
		var password_checkObj = document.registerForm.password_check;
		
		var flagObj = document.registerForm.flag;
		var idObj = document.registerForm.id;
		
		//getting values
		if (passwordObj.value !== password_checkObj.value){
			alert("비밀번호를 확인하세요!");
			
			//setting values
			passwordObj.value = "";
			password_checkObj.value = "";
			
			//return값 설정
			return false;
		}
		
		//flagObj.value : 인증받은 아이디 (idcheck-ok.jsp 팝업에서 할당한 아이디)
		//idObj.value : 사용자가 입력한 아이디
		if(flagObj.value !== idObj.value){
			alert("인증받은 아이디가 아닙니다.\n아이디 중복확인을 하세요!")
			return false;
		}
	}
	
	function CheckId(){
		var id = document.registerForm.id.value;
		if (id === ""){
			alert("아이디를 입력하세요");
		} else {
			var path = "front?command=idcheck&id=" + id;
			window.open(path, "idpopup", 
					"width=450, height=250, top=150, left=200");
		}
	}
</script>
</head>
<body>
	<div class="container">
		<a href="index.jsp"><img class="home-image" src="home.png">Home</a>
		<hr>
		<%-- CheckPassword() 
			: password와 password_check 같은 지 여부 확인 후 return--%>
		<form action="front" method="POST"
			name="registerForm" onsubmit="return CheckPassword()">
			<input type="hidden" name="command" value="register">
			<%-- 아이디 중복 확인을 위한 hidden --%>
			<input type="hidden" name="flag" value="">
			아이디 <input type="text" name="id" required="required">
			<input type="button" value="중복확인" onclick="CheckId()"><br>
			패스워드 <input type="password" name="password" required="required"><br>
			패스워드 확인 <input type="password" name="password_check" required="required"><br>
			이름 <input type="text" name="name" required="required"><br>
			주소 <input type="text" name="address" required="required"><br>
			<input type="submit" value="가입하기">
		</form>
		
	</div>
</body>
</html>

 

/register-result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>회원가입 완료</title>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
</head>
<body>
	<div class="container">
		<a href="index.jsp"><img class="home-image" src="home.png">Home</a>
		<hr>
		회원가입이 완료되었습니다.<br>
		축하드립니다!<br>
		
	</div>
</body>
</html>

--  6번 기능 :  아이디 중복 체크 기능 (팝업)

                               

/idcheck-ok.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>사용 가능 아이디</title>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<script type="text/javascript">
	function closePopup() {
		
		//이 팝업창을 실행 시킨 창은 opener 객체이다.
		//opener 객체를 가져온다
		var of = window.opener.registerForm;
		
		//flag값을 id로 바꿔주기
		of.flag.value = "<%=request.getParameter("id")%>";
		
		//password로 마우스 커서 옮기기
		of.password.focus();
		
		//자신(팝업창)을 종료한다
		self.close();
	}
</script>
</head>
<body bgcolor="yellow" onunload="closePopup()">
	<%=request.getParameter("id")%>는 사용 가능한 아이디입니다.
	<br>
	<br>
	<br>
	<input type="button" value="확인" onclick="closePopup()">
</body>
</html>

 

/idcheck-fail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<head>
<meta charset="UTF-8">
<title>사용 불가 아이디</title>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<script type="text/javascript">	
	function closePopup(){
		
		//이 팝업창을 실행 시킨 창은 opener 객체이다.
		//opener 안에 있는 id 객체를 가져온다
		var idObj = opener.document.registerForm.id;
		//hidden의 flag도 가져온다
		var flagObj = opener.document.registerForm.flag;
		
		//id + flag 초기화 시키고 & id로 마우스 커서 옮기기
		idObj.value="";
		flagObj.value= "";
		idObj.focus();
		
		//자신(팝업창)을 종료한다
		self.close();
	}
</script>
</head>
<body bgcolor="orange" onunload="closePopup()">
	<%=request.getParameter("id") %>는 사용 불가능한 아이디입니다.
	<br><br><br>
	<input type="button" value="확인" onclick="closePopup()">
</body>
</html>

Controller

 

/DispatcherServlet.java

/controller.java

https://creamilk88.tistory.com/103 에서 제공하는 코드와 동일합니다. 

 

 

/ HandlerMapping.java

package org.kosta.controller;
/*
 * 개별 컨트롤러 객체 생성을 전담하는 팩토리 클래스
 */
public class HandlerMapping {
	// singleton pattern으로 객체 생성
	private static HandlerMapping instance = new HandlerMapping();
	private HandlerMapping() { }
	public static HandlerMapping getInstance() {
		return instance;
	}
	
	/* create method() 생성
	 * command에 따라 개별의 Controller를 만들어주는 기능
	 */
	public Controller create(String command) {
		Controller controller = null;
		
		if(command.contentEquals("findmemberbyid"))
			controller = new FindMemberByIdController();
		else if(command.contentEquals("login"))
			controller = new LoginController();
		else if(command.contentEquals("logout"))
			controller = new LogoutController();
		else if(command.contentEquals("updateMember"))
			controller = new UpdateMemberController();
		else if(command.contentEquals("register"))
			controller = new RegisterController();
		else if(command.contentEquals("idcheck"))
			controller = new IdCheckController();
		return controller;
	}
}

-- 4번 기능 : 회원 정보 수정 (UDPATE/SET) 기능 controller

: 로그인에서 이용한 session을 그대로 유지하여 이용한다.

/UpdateMemberController.java

package org.kosta.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;

public class UpdateMemberController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String url = null;

		// request.getSession(false)를 통해 새로운 세션 생성을 방지한다!
		HttpSession session = request.getSession(false);

		// <로그인 여부 확인>
		// 1. session이 있고 + 2. session 정보가 있으면,
		if (session != null && session.getAttribute("mvo") != null) {
			
			// 1) update-form.jsp로부터 정보를 받아온다.
			String id = request.getParameter("id");
			String password = request.getParameter("password");
			String name = request.getParameter("name");
			String address = request.getParameter("address");

			MemberVO updateMemberVO = new MemberVO(id, password, name, address);

			// 2) DAO(Moel)과 연동해서, update를 실행해준다.
			MemberDAO.getInstance().updateMember(updateMemberVO);
			
			// 3) session에 새로 수정된 정보를 담아준다.
			session.setAttribute("mvo", updateMemberVO);
			
			// 4) url을 View(update-result.jsp)에 redirect방식으로 보낸다.
			url = "redirect:update-result.jsp";

			// session이 없으면 home(시작페이지)로 넘긴다.
		} else {
			url = "redirect:index.jsp";
		}

		return url;
	}

}

 

-- 5번 기능 :   회원 가입 기능 (INSERT) controller

/RegisterController.java

package org.kosta.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;

public class RegisterController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) 
			throws Exception {
		
		//register-form.jsp에서 form에 입력된 값 받아오기
		String id = request.getParameter("id");
		String password = request.getParameter("password");
		String name = request.getParameter("name");
		String address = request.getParameter("address");
		
		MemberVO registerMemberVO = new MemberVO(id, password, name, address);
		
		// VO 존재 유무 확인
		if (registerMemberVO != null) { //VO가 있으면
			//Model(DAO)과 연동
			MemberDAO.getInstance().register(registerMemberVO);
			
			// 연동 결과를 request에 담아 register-result와 공유
			request.setAttribute("mvo", registerMemberVO);
		} 
		
		//redirect 방식으로 view로 이동
		return "redirect:register-result.jsp";
	}

}

 

-- 6번 기능 :  회원 가입 시, 아이디 중복 확인 기능 controller

/IdCheckController.java

package org.kosta.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.kosta.model.MemberDAO;

public class IdCheckController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		// register-form.jsp에서 form에 입력된 id 받아오기
		String id = request.getParameter("id");

		// Model(DAO)와 연동
		// DAO.idCheck는 중복 아이디가 있으면 true, 없으면 false
		boolean flag = MemberDAO.getInstance().idCheck(id);

		// id 중복 여부 확인
		if (flag) // 중복 아이디가 없으면
			return "idcheck-fail.jsp"; // fail로
		else // 중복 아이디가 있으면
			return "idcheck-ok.jsp"; // ok로

	}
}

 

브라우저 결과 화면

 

 

728x90
반응형