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

[JSP] Semi-Project | Model2 MVC 기반 고객관리 웹어플리케이션 (회원가입, 로그인)

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

[ 요구사항 ]

고객은 해당 사이트에 회원 가입이 가능하다.

> 회원가입 시, 입력해야 하는 정보는 '아이디', '패스워드', '이름', '주소', '생년월일'이다.

> 추가로 시스템 상에서 '가입일시'는 자동으로 자장되도록 한다.

> 회원 가입 시, 아이디 중복 확인은 반드시 필요하다.

 

회원 가입 후 로그인하면,

1) "[고객명]님" 메세지를 제공하고, 

2) 마이페이지 링크를 제공한다.

 

마이페이지에서는 아래와 같이 정보를 제공한다.

아이디 : [아이디]

이름 : [이름]

주소: [주소]

생일 : [연도.월.일] (만 [만나이] 세) 

가입일시 : [연도.월.일 시:분:초]

 

사이트에 고객이 접속했을 때, 첫 화면(welcome file)에서는 

아래와 같이 가입한 고객 인원이 제공된다.(DB 바로 연동하여 보여주기-forward actiontag)

현재 고객 [인원]명

로그인 폼

회원가입 링크


[ 요구사항 분석 ]

UseCase Diagram


DataBase DDL Table

CREATE TABLE customer(
	id VARCHAR2(100) PRIMARY KEY,
	pass VARCHAR2(100) NOT NULL,
	name VARCHAR2(100) NOT NULL,
	address VARCHAR2(100) NOT NULL,
	birthday date NOT NULL,
	regdate date NOT NULL
)

File List

 


[ 구현 코드 ] 

 

Model

/CustomerVO.java

package org.kosta.model;

public class CustomerVO {
	private String id;
	private String password;
	private String name;
	private String address;
	private String birthday;
	private String regdate;
	private int age;

	@Override
	public String toString() {
		return "CustomerVO [id=" + id + ", password=" + password + ", name=" + name + ", address=" + address
				+ ", birthday=" + birthday + ", regdate=" + regdate + ", age=" + age + "]";
	}
	
	public CustomerVO() {
		super();
	}
	

	public CustomerVO(String id, String password){
		this.id = id;
		this.password = password;
	}

	public CustomerVO(String id, String password, String name, String address, String birthday, String regdate){
		super();
		this.id = id;
		this.password = password;
		this.name = name;
		this.address = address;
		this.birthday = birthday;
		this.regdate = regdate;
	}
	
	public CustomerVO(String id, String password, String name, String address, String birthday, String regdate,
			int age) {
		super();
		this.id = id;
		this.password = password;
		this.name = name;
		this.address = address;
		this.birthday = birthday;
		this.regdate = regdate;
		this.age = age;
	}


	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getBirthday() {
		return birthday;
	}

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

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

 

/CustomerDAO.java

1) DAO에 Singleton Design Pattern을 적용한다.

    : 시스템 상에서 단 한번 객체 생성을 하고 여러 곳에서 공유해서 사용하도록 한다.

2) DBCP를 이용해 driver loading & connection pool을 생성한다.

   : connection pool은 DataSourceManager class의 dataSourse을 통해 생성하며,

     connection을 빌려오고 반납하는 역할을 한다.

package org.kosta.model;

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

import javax.sql.DataSource;


//singleton pattern 적용
//DBCP 사용
public class CustomerDAO {
	private static CustomerDAO instance = new CustomerDAO();
	// DataSourceManger에 있는 DBCP 이용 (connection pool)
	private DataSource dataSource;

	private CustomerDAO() {
		// DBCP를 통해, driver loading & connection 빌려오기
		// 빌려와서 dataSource에 할당
		this.dataSource = DataSourceManager.getInstance().getDataSource();
	}

	public static CustomerDAO getInstance() {
		return instance;
	}

	// closeAll method 1 (pstmt, con)
	public void closeAll(PreparedStatement pstmt, Connection con) throws SQLException {
		if (pstmt != null)
			pstmt.close();
		// Connection을 dbcp에 반납한다(소멸하는 것이 아니다!)
		if (con != null)
			con.close();
	}

	// closeAll method 2 (rs, pstmt, con)
	public void closeAll(ResultSet rs, PreparedStatement pstmt, Connection con) throws SQLException {
		if (rs != null)
			rs.close();
		closeAll(pstmt, con);
	}

	/*
	 * 1번 기능 : 총 회원수 totalCustomerCount
	 */
	public int totalCustomerCount() throws SQLException {
		int count = 0;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			//dbcp로부터 connection을 빌려온다
			con = dataSource.getConnection();
			
			String sql = "SELECT COUNT(*) FROM customer";
			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} finally {
			closeAll(rs, pstmt, con);
		}
		return count;
	}
	
	/*
	 * 2번 기능 : 회원가입 signIn 
	 */
	public void signIn(CustomerVO vo) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		
		try {
			con = dataSource.getConnection();
			String sql = "INSERT INTO customer VALUES(?, ?, ?, ?, ?, sysdate)";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, vo.getId());
			pstmt.setString(2, vo.getPassword());
			pstmt.setString(3, vo.getName());
			pstmt.setString(4, vo.getAddress());
			pstmt.setString(5, vo.getBirthday());
			pstmt.executeUpdate();
			
		} finally {
			closeAll(pstmt, con);
		}
	}
	
	/*
	 * 3번 기능 : 아이디 중복 확인 checkDuplicatedId
	 * - 중복된 아이디가 없으면 true(ok), 있으면 false (fail)
	 */
	public boolean checkDuplicatedId(String id) throws SQLException {
		boolean flag = true;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = dataSource.getConnection();
			String sql = "SELECT COUNT(*) FROM customer WHERE id=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			if (rs.next() && rs.getInt(1) > 0) {
				flag = false;
			}
		} finally {
			closeAll(rs, pstmt, con);
		}
		return flag;
	}
	
	/*
	 * 4번 기능 : 로그인 login
	 */
	public CustomerVO login(CustomerVO inputVO) throws SQLException {
		CustomerVO vo = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = dataSource.getConnection();
			String sql = "SELECT id, name, address, birthday, regdate, "
					+ "TRUNC(MONTHS_BETWEEN(sysdate, birthday) / 12)"
					+ " FROM customer "
					+ "WHERE id=? AND password=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, inputVO.getId());
			pstmt.setString(2, inputVO.getPassword());
			rs = pstmt.executeQuery();
			//id와 password가 일치하는 것이 나올때만 rs에 값이 있다
			if (rs.next()) {
				vo = new CustomerVO(rs.getString(1), null, rs.getString(2),
						rs.getString(3), rs.getString(4),
						rs.getString(5), rs.getInt(6));
			}
		} finally {
			closeAll(rs, pstmt, con);
		}
		return vo;
	}
	
	
}// class

 


View

/welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<style type="text/css">
.content {
	height: 400px;
}
/*footer tag 꾸미기*/
footer {
	background-color: black;
	color: white;
	padding: 15px;
}
</style>

<title>WELCOME</title>
</head>
<body>
	<!-- header.jsp include -->
	<jsp:include page="header.jsp"></jsp:include>
	
	<div class="content">
		<jsp:forward page="front">
			<jsp:param value="totalcount" name="command"/>
		</jsp:forward>
	
	</div>
	
	<!-- footer.jsp include -->
	<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>

 

/header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" href="welcome.jsp">Home</a>
    </div>
    <ul class="nav navbar-nav">
    </ul>
    <ul class="nav navbar-nav navbar-right">
    <%  HttpSession session = request.getSession(false); 
    	//로그인 상태면 header에 [mypage] & [logout] 표시
    	if (session != null && session.getAttribute("cvo")!=null) {
    %>
    	<li><a href="mypage.jsp"><span class="glyphicon glyphicon-user"></span> 마이페이지</a></li>
   		<li><a href="front?command=logout"><span class="glyphicon glyphicon-log-in"></span> Logout</a></li>
    <% } else { 
    	//로그인 상태가 아니면 header에 [signin] & [login] 표시 %>  
	    <li><a href="signin-form.jsp"><span class="glyphicon glyphicon-user"></span> Sign In</a></li>
	    <li><a href="login-form.jsp"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
    <% } %>
    	
    </ul>
  </div>
</nav>

 

/footer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<footer>
	<p>파프리카 블로그</p>
</footer>

 

/error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
	에러가 발생했습니다.<br>
	콘솔을 확인하세요 ~ !
	<img src="milk.jpg">
</body>
</html>

 


--  UseCase 1  : welcome.jsp에 총 회원수 forward actiontag 방식으로 보여주기

 

/totalcount.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<style type="text/css">
.content {
	height: 400px;
}
footer {
	background-color: black;
	color: white;
	padding: 15px;
}
</style>
<title>총 회원수</title>
</head>
<body>
	<!-- header.jsp include -->
	<jsp:include page="header.jsp"></jsp:include>
	
	<div class="content">
		<h3>
		총 회원 수 : <%=request.getAttribute("count") %> 명
		</h3>
	</div>
	
	<!-- footer.jsp include -->
	<jsp:include page="footer.jsp"></jsp:include>

</body>
</html>

--  UseCase 2 : 회원가입 ( 아이디 중복화인 (팝업) + 패스워드 확인 )

 

/signin-form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<style type="text/css">
.content {
	height: 500px;
}
footer {
	background-color: black;
	color: white;
	padding: 15px;
}
</style>

<title>회원가입</title>
<script type="text/javascript">
	function CheckPassword() {
		// 패스워드 같은지 여부 확인
		var passObj = document.signInForm.password;
		var passcheckObj = document.signInForm.password_check;
		
		if (passObj.value !== passcheckObj.value){
			alert("비밀번호를 확인하세요.");
			
			passObj.value = "";
			passcheckObj.value= "";
			
			return false;
		}
		
		// 아이디 중복 체크 확인했는지 여부 확인
		//flagObj.value : 인증받은 아이디 (check-id-ok.jsp 팝업에서 할당한 아이디)
		//idObj.value : 사용자가 입력한 아이디
		var flagObj = document.signInForm.flag;
		var flagId = document.signInForm.id;
		
		if (flagObj.value !== flagId.value){
			alert("인증받은 아이디가 아닙니다.\n아이디 '중복확인'을 해주세요");
	
			return false;
		}
		
	}
	
	function CheckId() {
		var id = document.signInForm.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>
	<jsp:include page="header.jsp"></jsp:include>
	
	<div class="container">
		<div class="content">
		<div class="col-sm-1"></div><h2>Sign In</h2>
		<form class="form-horizontal" action="front" method="POST" 
			name="signInForm" onsubmit="return CheckPassword()">
			
			<input type="hidden" value="signin" name="command"><br>
			<input type="hidden" value="" name="flag">
			
			<div class="form-group">
      			<label class="control-label col-sm-2" for="id">아이디:</label>
      				<div class="col-sm-3">
        			<input type="text" class="form-control" name="id" required="required"
						placeholder="아이디">
      				</div>
					<input type="button" value="중복확인" class="btn btn-warning btn-sm"
					onclick="CheckId()">
    		</div>
    		
			<div class="form-group">
      			<label class="control-label col-sm-2" for="password">패스워드:</label>
      				<div class="col-sm-3">
        			<input type="password" class="form-control" name="password" 
        				required="required" placeholder="패스워드">
      				</div>
      				<div class="col-sm-8"></div><br>
    		</div>
    		
			<div class="form-group">
      			<label class="control-label col-sm-2" for="password_check">패스워드 확인:</label>
      					<div class="col-sm-3">
        			<input type="password" class="form-control"  name="password_check" 
        				required="required"	placeholder="패스워드 확인">
      				</div>
      				<div class="col-sm-8"></div><br>
    		</div>
    		
			<div class="form-group">
      			<label class="control-label col-sm-2" for="name">이름:</label>
      				<div class="col-sm-3">
        			<input type="text" class="form-control" name="name" required="required"
						placeholder="이름">
      				</div>
      				<div class="col-sm-8"></div><br>
    		</div>
 		
			<div class="form-group">
      			<label class="control-label col-sm-2" for="address">주소:</label>
      				<div class="col-sm-3">
        			<input type="text" class="form-control" name="address" required="required"
						placeholder="주소">
      				</div>
     				<div class="col-sm-8"></div><br>
 	  		</div>
    		
			<div class="form-group">
      			<label class="control-label col-sm-2" for="birthday">생일:</label>
      				<div class="col-sm-3">
        			<input type="date" class="form-control" name="birthday" 
        				required="required">
     				</div>
     				<div class="col-sm-8"></div><br><br>
    		</div>
    		
			<div class="col-sm-4"></div>
			<input type="submit" value="가입하기" class="btn btn-success btn-sm"><br>
		</form>
		</div>
	</div>
	
	<!-- footer.jsp include -->
	<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>

 

/check-id-ok.jsp (팝업)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사용 가능 아이디</title>
<script type="text/javascript">
	function closePopup() {
		//이 팝업창을 실행 시킨 창은 opener 객체이다.
		//opener 객체를 가져온다
		var of = window.opener.signInForm;
		
		//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>

 

/check-id-fail.jsp (팝업)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사용 불가 아이디</title>
<script type="text/javascript">

	function closePopup() {
		
		//opener 안에 있는 id 객체를 가져온다
		var idObj = opener.signInForm.id;
		//hidden의 flag도 가져온다
		var flagObj = opener.signInForm.flag;
		
		//id + flag 초기화 시키고 & id로 마우스 커서 옮기기
		idObj.value = "";
		flagObj.value = "";
		idObj.focus();
		
		//자신(팝업창)을 종료한다
		self.close();
	}

</script>
</head>
<body bgcolor="lime" onunload="closePopup()">
	<%=request.getParameter("id") %>는 사용 가능이 불가한 아이디입니다.
	<br><br><br>
	<input type="button" value="확인" onclick="closePopup()">
</body>
</html>

--  UseCase 3 : 로그인 

 

/login-form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<style type="text/css">
.content {
	height: 400px;
}

footer {
	background-color: black;
	color: white;
	padding: 15px;
}
</style>

<title>로그인</title>
</head>
<body>
	<jsp:include page="header.jsp"></jsp:include>

	<div class="container">
	<h2>Login</h2>
	<div class="content">
		<form class="form-horizontal" action="front" method="POST">
			<input type="hidden" name="command" value="login">
			<br><br>
			<div class="col-sm-4 sm-offset-7">
			<div class="form-group">
				<label for="id">ID:</label> 
				<input type="text" class="form-control"  
					   name="id" required="required" 
					   placeholder="아이디를 입력하세요">
			</div>
			<div class="form-group">
				<label for="pwd">Password:</label> 
				<input type="password" class="form-control" 
						name="password" required="required"
						placeholder="비밀번호를 입력하세요"><br>
			<button type="submit" class="btn btn-default">로그인</button>
			</div>
			</div>
		</form>
	</div>
	</div>

	<jsp:include page="footer.jsp"></jsp:include>

</body>
</html>

 

/login-fail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<style type="text/css">
.content {
	height: 400px;
}
footer {
	background-color: black;
	color: white;
	padding: 15px;
}
</style>
<title>로그인 실패</title>
</head>
<body>
	<jsp:include page="header.jsp"></jsp:include>
	
	<div class="content">
		아이디와 패스워드를 확인해주세요.
	</div>
	
	<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>

--  UseCase 4 : 로그인 시, 마이페이지를 통해 회원정보 보여주기

 

/mypage.jsp

<%@page import="org.kosta.model.CustomerVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<style type="text/css">
.content {
	height: 400px;
}
footer {
	background-color: black;
	color: white;
	padding: 15px;
}
</style>
<title>마이페이지</title>

</head>
<body>
	<jsp:include page="header.jsp"></jsp:include>
	
	<% HttpSession session = request.getSession(false);
	   if (session !=null && session.getAttribute("cvo") != null) {
	   		CustomerVO cvo = (CustomerVO) session.getAttribute("cvo");
    %>
	    
	<div class="content">
		<div class="container">
		  <h2>My Page</h2>
		  <ul class="list-group">
		    <li class="list-group-item"><strong>아이디 | </strong><%=cvo.getId() %></li>
		    <li class="list-group-item"><strong>이름 | </strong><%=cvo.getName() %></li>
		    <li class="list-group-item"><strong>주소 | </strong><%=cvo.getAddress() %></li>
		    <li class="list-group-item"><strong>생년월일(나이) | </strong><%=cvo.getBirthday().substring(0, 10) %>
			(만 나이: <%=cvo.getAge() %>세)</li>
		    <li class="list-group-item"><strong>가입일시 | </strong><%=cvo.getRegdate() %></li>
		  </ul>
		</div>
		<% } %>
	</div>
	
	<jsp:include page="footer.jsp"></jsp:include>

</body>
</html>

Controller

/Controller.java

→ 개별 Controller 객체를 표준화하는 interface

: 컨트롤러 구현체를 사용하는 측에서 단일한 방법 (추상메서드) 으로

다양한 컨트롤러 구현체를 실행하게 할 수 있도록 계층구조를 형성하는 역할

package org.kosta.controller;

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

public interface Controller {
	public String execute(HttpServletRequest request, HttpServletResponse response)
		throws Exception;
}

 

/ HandlerMapping.java

컨트롤러 객체 생성을 전담하는 Factory 객체

DispatcherSerlvet과 개별 Controller들과의 결합도를 낮추는 역할

package org.kosta.controller;

public class HandlerMapping {
	private static HandlerMapping instance = new HandlerMapping();
	private HandlerMapping() {}
	public static HandlerMapping getInstance() {
		return instance;
	}
	
	public Controller create(String command) {
		Controller controller = null;
		if (command.contentEquals("totalcount")) {
			controller = new TotalCountController();
		} else if (command.contentEquals("signin")) {
			controller = new SignInController();
		} else if (command.contentEquals("idcheck")) {
			controller = new CheckDuplicatedIdController();
		} else if (command.contentEquals("login")) {
			controller = new LoginController();
		} else if (command.contentEquals("logout")) {
			controller = new LogoutController();
		}
		return controller;
	}
}

 

/DispatcherServlet.java

handleRequest method 작동 방식

1. 에러(예외) 발생 시, 콘솔에 메세지 발생 경로 출력 후,  error.jsp로  redirect 방식으로 view로 이동한다.

2. 클라이언트가 전송한 command 정보를 받는다.

3. HandlerMapping 을 이용해 개별 컨트롤러 객체를 컨트롤러 인터페이스 타입으로 반환받는다.

4. 개별 컨트롤러를 실행한다.

5. 실행 후 반환된 String url 정보를 이용해,

     forward 방식 or redirect 방식으로 view로 이동해 응답하게 한다.

package org.kosta.controller;

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


@WebServlet("/front")
public class DispatcherSerlvet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		this.HandleRequest(request, response);
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		this.HandleRequest(request, response);
	}
	
	protected void HandleRequest(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		try {
			String command = request.getParameter("command");
			Controller controller = HandlerMapping.getInstance().create(command);
			String url = controller.execute(request, response).trim();
			if (url.startsWith("redirect:"))
				response.sendRedirect(url.substring(9));
			else
				request.getRequestDispatcher(url).forward(request, response);	
		} catch (Exception e) {
			e.printStackTrace();
			response.sendRedirect("error.jsp");
		}
	}
}

 


---  UseCase 1  : 총 회원 수 반환 Controller

 

/TotalCountController.java

package org.kosta.controller;

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

import org.kosta.model.CustomerDAO;

public class TotalCountController implements Controller {
	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) 
			throws Exception {
		int count = CustomerDAO.getInstance().totalCustomerCount();
		request.setAttribute("count", count);
		return "totalcount.jsp";
	}
}

--  UseCase 2 : 회원가입 ( 아이디 중복화인 (팝업) + 패스워드 확인 ) Controller

 

/SignInController.java

package org.kosta.controller;

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

import org.kosta.model.CustomerDAO;
import org.kosta.model.CustomerVO;

public class SignInController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) 
			throws Exception {

		String id = request.getParameter("id");
		String password = request.getParameter("password");
		String name = request.getParameter("name");
		String address = request.getParameter("address");
		String birthday = request.getParameter("birthday");
		
		CustomerVO cvo = new CustomerVO();
		cvo.setId(id);
		cvo.setPassword(password);
		cvo.setName(name);
		cvo.setAddress(address);
		cvo.setBirthday(birthday);
		
		//VO 존재 유무 확인
		if (cvo != null) 
			//모델과 연동하여 DB에 정보 INSERT
			CustomerDAO.getInstance().signIn(cvo);
		
		return "redirect:welcome.jsp";
	}

}

--  UseCase 2-1 : 회원가입 시, DB에 중복된 아이디가 있는 지 확인하는 기능 Controller

 

/CheckDuplicatedIdController.java

package org.kosta.controller;

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

import org.kosta.model.CustomerDAO;

public class CheckDuplicatedIdController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) 
			throws Exception {
		String url = "";
		
		String id = request.getParameter("id");
		//중복된 아이디가 없으면 true(ok), 있으면 false (fail)
		Boolean flag = CustomerDAO.getInstance().checkDuplicatedId(id);
		if (flag)
			url = "check-id-ok.jsp";
		else
			url = "check-id-fail.jsp";		
		return url;
	}

}

--  UseCase 3 : 로그인  Controller + 로그아웃  Controller

 

/LoginController.java

package org.kosta.controller;

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

import org.kosta.model.CustomerDAO;
import org.kosta.model.CustomerVO;

public class LoginController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		String url = "";
		String id = request.getParameter("id");
		String password = request.getParameter("password");
		
		//vo : 입력받은 값으로 만든 MemebrVO 객체		
		CustomerVO vo = new CustomerVO(id, password);
		//cvo : model과 연동하여 vo를 넣어 결과값으로 받은 CustomerVO 객체
		CustomerVO cvo = CustomerDAO.getInstance().login(vo);
		
		if (cvo == null) { //로그인 실패
			url = "redirect:login-fail.jsp";
		} else { //로그인 성공
			url = "redirect:login-ok.jsp";
			//세션 생성
			HttpSession session = request.getSession();
			//세션에 정보 할당 - View에 정보 공유
			session.setAttribute("cvo", cvo);
		}
		
		return url;
	}

}

 

/LogoutController.java

package org.kosta.controller;

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

public class LogoutController implements Controller {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) 
			throws Exception {
		HttpSession session = request.getSession(false);
		
		//로그인 정보가 있으면 세션정보 초기화
		if (session != null)
			session.invalidate();
		
		return "redirect:welcome.jsp";
	}

}

브라우저 결과 화면

 

 

728x90
반응형