member.properties
- 회원가입이나 로그인 같은 기능을 구현하여 실행하기 위해 member.properties를 추가해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# Form Change
main.do=jsp.member.action.MemberFormChangeAction
LoginForm.do=jsp.member.action.MemberFormChangeAction
SignUpForm.do=jsp.member.action.MemberFormChangeAction
ResultForm.do=jsp.member.action.MemberFormChangeAction
PwdCheckForm.do=jsp.member.action.MemberFormChangeAction
MemberDetail.do=jsp.member.action.MemberFormChangeAction
# Action
MemberLoginAction.do=jsp.member.action.MemberLoginAction
MemberLogoutAction.do=jsp.member.action.MemberLogoutAction
MemberSignUpAction.do=jsp.member.action.MemberSignUpAction
MemberDetailAction.do=jsp.member.action.MemberDetailAction
MemberModifyAction.do=jsp.member.action.MemberModifyAction
MemberDeleteAction.do=jsp.member.action.MemberDeleteAction
|
cs |
- 각각 어떤 식으로 구현되는지는 후술 하겠습니다.
SignUpForm.jsp
- 회원가입 화면을 구현해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>회원가입 페이지</title>
<style>
.py-4{
margin-top: 50px;
}
.or{
position: relative;
}
.or:before{
content: '';
height: 1px;
background: linear-gradient(to right,silver,silver,rgba(255,255,255,0),rgba(255,255,255,0),silver,silver);
position: absolute;
left: 0;
top: 50%;
width: 100%;
z-index: 0;
}
#loginButton{
text-decoration: underline;
color: #0064FF;
}
#loginBtn:hover{
cursor: pointer;
}
</style>
<script type="text/javascript">
//화면전환
function changeSignUpView(){
// 로그인 버튼 클릭시 로그인 화면으로 이동
{
location.href="LoginForm.do";
}
}
//회원가입 폼에 입력값들이 입력됐는지 올바른 값이 입력됐는지 검사
function signUpCheckAction() {
//form 태그 가져오기
let formName = document.signUpInfo;
//form태그의 name값으로 value 가져오기
let inputEmail = formName.memberEmail.value;
let inputName = formName.memberName.value;
let inputID = formName.memberID.value;
let inputPWD = formName.memberPWD.value;
let pwdCheck = formName.memberPWDCheck.value;
if(inputEmail == "") { //이메일이 없으면
alert("이메일을 입력하세요");
formName.memberEmail.focus();
return false;
}
if(inputName == "") { //이름이 없으면
alert("이름을 입력하세요");
formName.memberName.focus();
return false;
}
if(inputID == "") { //아이디가 없으면
alert("아이디를 입력하세요");
formName.memberID.focus();
return false;
}
if(inputPWD == "") { //비밀번호가 없으면
alert("비밀번호를 입력하세요");
formName.memberPWD.focus();
return false;
}
if(inputPWD != pwdCheck) { //비밀번호가 동일하지 않으면
alert("비밀번호가 동일하지 않습니다.");
formName.memberPWDCheck.focus();
return false;
}
}
</script>
</head>
<body class="text-center">
<section class="py-4">
<div class="container">
<div class="row d-flex align-items-center justify-content-center">
<div style="max-width:420px;">
<form action="MemberSignUpAction.do" name="signUpInfo" class="bg-white border py-4 px-5" method="post" onsubmit="return signUpCheckAction()">
<div class="text-center mb-3">
<i class="fab fa-bootstrap fa-5x text-secondary mb-2"></i>
<p class="text-muted fw-bold">
<img class="mb-4" src="${pageContext.request.contextPath}/docs/5.1/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
</p>
</div>
<div class="form-floating mb-3">
<input class="form-control" name="memberEmail" placeholder="Email" type="email" /><label>이메일</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" name="memberName" placeholder="UserName" type="text" /><label>이름</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" name="memberID" placeholder="ID" type="text" /><label>아이디</label>
</div>
<div class="mb-2">
<button class="btn btn-primary fw-bold w-100 bg-gradient" type="submit" onclick="idCheck()">아이디 중복 확인</button>
</div>
<div class="form-floating mb-3">
<input class="form-control" name="memberPWD" placeholder="Password" type="password" /><label>비밀번호</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" name="memberPWDCheck" placeholder="Password" type="password" /><label>비밀번호 확인</label>
</div>
<div class="mb-2">
<button class="btn btn-primary fw-bold w-100 bg-gradient" type="submit">회원 가입</button>
</div>
</form>
<div class="bg-white py-4 px-5 text-center border mt-4">
<p class="m-0">
계정이 있으신가요 ? <a id="loginButton" onclick="changeSignUpView()">로그인하러 가기</a>
</p>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
|
cs |
- 화면은 부트스트랩을 이용해 구현했습니다.
- changeSignUpview()와 signUpcheckAction() function을 구현합니다.
- 회원가입 페이지에서 이미 아이디가 있어서 로그인 화면으로 넘어가고자 하는 경우를 위해서
로그인 화면으로 넘어갈 수 있도록 화면을 구현하고 기능을 구현했습니다.(changeSignUpview())
- 회원가입 페이지에서는 모든 값이 입력됐는지 확인해야 하고,
비밀번호를 두 번 입력하게 하여 비밀번호 입력값을 한 번 더 확인해야 합니다.
또한, 아이디 중복 확인으로 이미 동일 아이디로 가입한 아이디가 있는지 확인해야 합니다.
(아직 해당 기능을 구현하지 않았습니다. 후에 AJAX를 활용해 해당 파트를 구현할 예정입니다.)
- form 태그의 name값을 활용해 각 value를 확인해 입력값이 있는지 확인합니다.(44~75번째 줄)
- 동일한 비밀번호를 두 번 입력하게 하여 비밀번호를 확인할 수 있도록 합니다.(76~80번째 줄)
- 해당 페이지는 form태그로 구성되어 있습니다.
- <form> 태그의 method 속성은 폼 데이터가 서버로 제출될 때 사용되는 HTTP 메서드를 나타냅니다.
- 메서드 속성 값으로는 GET과 POST 두 가지 중 하나를 선택할 수 있습니다.
- POST 방식은 GET 방식에 비해 보안성이 높기 때문에 회원 데이터를 처리해야 하는 경우
GET 방식보다는 POST 방식이 적합합니다.
- action은 폼 태그 내부의 데이터를 전송(submit) 했을 때 데이터를 보내는 곳의 URL을 지정합니다.
- 따라서 해당 데이터가 전송되면 'MemberSignUpAction.do'를 호출합니다.
회원가입 화면
- 구현된 회원가입 화면입니다.
- 위와 같이 정보를 입력하지 않고 회원가입을 시도하는 경우 경고창이 표시됩니다.
- 위와 같이 비밀번호를 동일하게 입력하지 않은 경우 경고창이 출력됩니다.
MemberSignUpAction.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package jsp.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import jsp.common.action.Action;
import jsp.common.action.ActionForward;
import jsp.member.model.MemberBean;
import jsp.member.model.MemberDAO;
public class MemberSignUpAction implements Action {
//회원가입 처리를 위한 Action 클래스
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = new ActionForward();
HttpSession session = request.getSession();
MemberDAO mDAO = MemberDAO.getInstance();
//입력된 정보 자바빈으로 세팅하기
MemberBean member = new MemberBean();
member.setMemberID(request.getParameter("memberID"));
member.setMemberPWD(request.getParameter("memberPWD"));
member.setMemberName(request.getParameter("memberName"));
member.setMemberEmail(request.getParameter("memberEmail"));
//insert 실행
mDAO.joinMember(member);
//session에 msg값 세팅하기
session.setAttribute("msg", "0");
//회원가입 후 화면 전환
forward.setRedirect(true);
forward.setPath("ResultForm.do");
return forward;
}
}
|
cs |
- 'SignUpForm.do'에서 form 태그의 데이터를 이용, 데이터베이스에 접근해
회원가입을 처리해 줄 'MemberSignUpAction' 클래스입니다.
- Action 클래스의 구현 클래스이므로 'ActionForward forward = new ActionForward()'로
새로운 ActionForward 객체를 생성하고 ActionForward 객체를 리턴할 수 있도록 합니다.
- 회원가입이나 회원정보 수정, 회원정보 삭제에 대한 결과 페이지(ResultForm.do)를 따로 구현할 예정입니다.
- 회원가입 결과를 결과 페이지에 넘겨주기 위해 session 객체를 생성하여 "msg"라는 변수에 "0"값을 저장합니다.
- MemberDAO의 joinMember 메서드입니다.
- SignUpForm에서 넘어온 값을 이용해 MemberBean의 값을 세팅해주고
세팅된 값으로 joinMember 메서드를 실행합니다.
ResultForm.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html lang="en">
<head>
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-si ze: 3.5rem;
}
}
</style>
<script type="text/javascript">
function changeResultView(value){
if(value == "0") // "네 로그인" 클릭시 로그인 화면으로 이동
{
location.href="LoginForm.do";
}
else if(value == "1") // "아니요" 클릭시 메인으로 이동
{
location.href="main.do";
}else if(value == "3") // "네 회원가입" 클릭시 메인으로 이동
{
location.href="SignUpForm.do";
}
}
</script>
<title>요청이 완료되었습니다.</title>
</head>
<body class="text-center">
<c:set var="msg" value="${sessionScope.msg}"/>
<c:choose>
<c:when test="${msg!=null && msg=='0'}">
<div class="modal modal-alert position-static d-block bg-secondary py-5" tabindex="-1" role="dialog" id="modalChoice">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-4 shadow">
<div class="modal-body p-4 text-center">
<h5 class="mb-0">로그인 하시겠습니까?</h5>
<p class="mb-0">회원가입한 정보로 로그인 해주세요.</p>
</div>
<div class="modal-footer flex-nowrap p-0">
<button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
onclick="changeResultView(0)"><strong>네. 로그인 하겠습니다.</strong></button>
<button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0" data-bs-dismiss="modal"
onclick="changeResultView(1)">아니요. 괜찮습니다.</button>
</div>
</div>
</div>
</div>
</c:when>
<c:when test="${msg!=null && msg=='1'}">
<div class="modal modal-alert position-static d-block bg-secondary py-5" tabindex="-1" role="dialog" id="modalChoice">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-4 shadow">
<div class="modal-body p-4 text-center">
<h5 class="mb-0">회원정보가 수정되었습니다.</h5>
<p class="mb-0">수정된 정보로 로그인 해주세요.</p>
</div>
<div class="modal-footer flex-nowrap p-0">
<button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
onclick="changeResultView(0)"><strong>네. 로그인 하겠습니다.</strong></button>
<button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0" data-bs-dismiss="modal"
onclick="changeResultView(1)">아니요. 괜찮습니다.</button>
</div>
</div>
</div>
</div>
</c:when>
<c:when test="${msg!=null && msg=='2'}">
<div class="modal modal-alert position-static d-block bg-secondary py-5" tabindex="-1" role="dialog" id="modalChoice">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-4 shadow">
<div class="modal-body p-4 text-center">
<h5 class="mb-0">회원정보가 삭제되었습니다.</h5>
<p class="mb-0">이용을 위해서는 회원가입이 필요합니다.</p>
</div>
<div class="modal-footer flex-nowrap p-0">
<button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
onclick="changeResultView(3)"><strong>네. 회원가입 하겠습니다.</strong></button>
<button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0" data-bs-dismiss="modal"
onclick="changeResultView(1)">아니요. 괜찮습니다.</button>
</div>
</div>
</div>
</div>
</c:when>
</c:choose>
</body>
</html>
|
cs |
- 회원가입, 회원 수정, 회원 삭제에 대한 동작 후 처리결과를 나타낼 결과 창입니다.
- JSTL과 각각 구현된 Action 클래스로 전달하는 msg 값에 따라서
다른 결과 화면을 출력하도록 화면을 구현했습니다.(41~90번째 줄)
- onclick() function을 추가해서 특정 버튼을 클릭할 경우
화면이 전환될 수 있도록 function을 추가했습니다.(22~36번째 줄)
- 회원가입이 성공하면 다음과 같은 결과창이 출력됩니다.
LoginForm.jsp
- 로그인 화면을 구현해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html lang="en">
<head>
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
#SignUpBtn{
text-decoration: underline;
color: #0064FF;
}
#SignUpBtn:hover{
cursor: pointer;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-si ze: 3.5rem;
}
}
</style>
<script type="text/javascript">
function changeLoginView(value){
// 회원가입 버튼 클릭시 회원가입 화면으로 이동
location.href="SignUpForm.do";
}
function loginCheckAction() {
let formName = document.loginInfo;
let inputID = formName.memberID.value;
let inputPWD = formName.memberPWD.value;
if(inputID == "") { //아이디가 없으면
alert("아이디를 입력하세요");
formName.memberID.focus();
return false;
}
if(inputPWD == "") { //비밀번호가 없으면
alert("비밀번호를 입력하세요");
formName.memberPWD.focus();
return false;
}
}
</script>
<link href = "${pageContext.request.contextPath}/css/signin.css" rel="stylesheet">
<title>로그인 페이지</title>
</head>
<body class="text-center">
<main class="form-signin">
<!-- post방식 -->
<form name="loginInfo" method="post" action="MemberLoginAction.do" onsubmit="return loginCheckAction()">
<img class="mb-4" src="${pageContext.request.contextPath}/docs/5.1/assets/brand/bootstrap-logo.svg" width="72" height="57">
<h1 class="h3 mb-3 fw-normal">로그인</h1>
<div class="form-floating">
<input type="text" class="form-control" id="floatingInput" name="memberID" placeholder="ID">
<label for="floatingInput">아이디를 입력해주세요.</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" name="memberPWD" placeholder="Password">
<label for="floatingPassword">비밀번호를 입력해주세요.</label>
</div>
<input class="w-100 btn btn-lg btn-primary" type="submit" value="로그인"></input>
<div class="py-4 px-5 text-center border mt-4">
<c:if test="${sessionScope.sessionID==null}">
<p class="m-0">
계정이 없으신가요 ? <br>
<a id="SignUpBtn" onclick="changeLoginView()" >회원가입하러 가기</a>
</p>
</c:if>
</div>
<p class="mt-5 mb-3 text-muted">© Determination</p>
</form>
</main>
<c:set var="failMessage" value="${requestScope.fail}"/>
<c:if test="${failMessage!=null}">
<c:choose>
<c:when test="${failMessage=='0'}">
<script type="text/javascript">
alert("사용자 정보가 일치하지 않습니다.");
</script>
</c:when>
<c:otherwise>
<script type="text/javascript">
alert("사용자 정보가 일치하지 않습니다.");
</script>
</c:otherwise>
</c:choose>
</c:if>
</body>
</html>
|
cs |
- 화면은 부트스트랩을 이용해 구현했습니다.
- 아이디가 없는 경우 회원 가입 페이지로 이동할 수 있도록 기능을 구현했습니다.
- onclick="ChangeLoginView()"를 추가하고 기능을 구현합니다.(77번째 줄)
- 'location.href="SignUpForm.do"'를 추가해 회원가입 화면으로 이동할 수 있도록 해줍니다.(30~34번째 줄)
- loginCheckAction()을 구현합니다. loginCheckAction()은 아이디나 비밀번호를 입력하지 않고
로그인을 시도할 경우 경고창을 띄우고 아이디나 비밀번호를 입력하고 로그인을 할 수 없게 합니다.(36~51번째 줄)
- JSTL을 사용해 failMessage 변수를 설정합니다.
- 해당 변수는 'requestScope.fail' 정보를 가지고 있습니다.
- 만약 'requestScope.fail'로 넘어온 정보가 있다면 아이디나 비밀번호가 일치하지 않다는 경고창을 띄웁니다.
- 파라미터로 전달되는 'fail'은 MemberLoginAction에서 후술 하겠습니다.
- 해당 페이지는 form태그로 구성되어 있습니다.
- 해당 데이터가 전송되면 'MemberLoginAction.do'를 호출합니다.
로그인 화면
- 구현된 로그인 화면은 다음과 같습니다.
- 위와 같이 아이디나 비밀번호 정보를 입력하지 않고 로그인을 시도하는 경우 경고창이 출력됩니다.
- 아이디나 비밀번호 정보가 일치하지 않는 경우 위와 같은 경고창이 출력됩니다.
MemberLoginAction.do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package jsp.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import jsp.common.action.Action;
import jsp.common.action.ActionForward;
import jsp.member.model.MemberDAO;
//로그인 처리를 담당하는 Action 클래스
public class MemberLoginAction implements Action{
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = new ActionForward();
//ActionForward 객체 생성
HttpSession session = request.getSession();
//HttpSession 객체 생성
//입력한 아이디와 비밀번호 가져오기
String id = request.getParameter("memberID");
String password = request.getParameter("memberPWD");
//DB에 접근해서 아이디와 비밀번호 확인하기
MemberDAO mDAO = MemberDAO.getInstance();
int check = mDAO.loginCheck(id, password);
//반환값이 0이면
if(check == 0) {
//fail 설정
request.setAttribute("fail", "0");
forward.setRedirect(false);
forward.setPath("LoginForm.do");
//반환값이 -1이면
} else if (check == -1) {
//fail 설정
request.setAttribute("fail", "-1");
forward.setRedirect(false);
forward.setPath("LoginForm.do");
//반환값이 1이면(로그인 성공)
} else if (check == 1) {
//세션에 아이디와 비밀번호 저장
session.setAttribute("memberID", id);
session.setAttribute("memberPWD", password);
forward.setRedirect(true);
forward.setPath("main.do");
}
return forward;
}
}
|
cs |
- 'LoginForm.do'에서 form 태그의 데이터를 이용해 데이터베이스에 접근해 정보를 확인하고
로그인을 처리해 줄 'MemberLoginAction' 클래스입니다.
- Action 클래스의 구현 클래스이므로 'ActionForward forward = new ActionForward()'로
새로운 ActionForward 객체를 생성하고 ActionForward 객체를 리턴할 수 있도록 합니다.
- 로그인에 성공할 경우 session에 아이디와 비밀번호를 저장하기 위해 HttpSession 객체를 생성합니다.
- request.setAttribute의 경우 하나의 request 후에 값이 반환됩니다. ex) 32번째 줄
반면에 session.setAttribute의 경우 session의 유지시간 동안 저장된 값이 유지됩니다. (46~47번째 줄)
- 로그인 정보의 경우 일정 시간 동안 유지되어야 하는 정보이기 때문에
session 객체를 생성해 값을 저장해줍니다.
- 로그인 실패의 경우 한 번 값을 반환하고 만료돼도 되는 정보이기 때문에 request.setAttribute를 사용합니다.
- MemberDAO의 loginCheck 메서드입니다.
- 로그인 화면에서 입력받은 데이터를 loginCheck의 파라미터로 이용해 DB에 접근합니다.
- 입력 받은 아이디와 비밀번호가 DB에 저장된 데이터가 다른 경우 '-1'이나 '0'을 반환합니다.
- 입력 받은 아이디와 비밀번호가 DB에 저장된 데이터와 일치하는 경우 '1'을 반환합니다.
- '-1'이나 '0'을 반환하는 경우 'LoginForm.do'에 'fail' 값으로 '-1'이나 '0'을 설정합니다.
- 전달받은 'fail'값이 있으면 LoginForm.do에서 '사용자 정보가 일치하지 않습니다.'라는 경고창을 출력합니다.
이번 글에서는 로그인과 회원가입과 관련된 Action 클래스, View 페이지, MemberDAO의 메서드 등을 알아봤습니다.
다음 글에서는 회원 정보 상세보기, 회원 정보 수정, 회원 정보 삭제를 구현하는 방법을 알아보겠습니다.
긴 글 읽어주셔서 감사하고 모르는 부분은 댓글 부탁드립니다!
댓글