커뮤니티 - 회원 가입 기능 구현 (23.07.07)

·2023년 7월 7일
0

Server

목록 보기
9/35
post-thumbnail

📝 회원 가입 기능 구현


💡VS Code

🔎 index.jsp

.
.
.

		                    <!-- 회원가입, ID/PW 찾기 영역 -->
		                    <article id="signup-find-area">

                                <!-- WEB-INF 폴더는 외부로부터 직접적으로 요청할 수 없는 폴더
                                    왜? 중요한 코드(자바, sql, 설정 관련)가 위치하는 폴더로서
                                        외부로부터 접근을 차단하기 위해서

                                    -> 대신 Servlet을 이용 내부 접근(forward)은 가능
                                
                                -->

		                        <!-- <a href="/community/WEB-INF/views/member/signUp.jsp">회원가입</a> -->

		                        <a href="/community/member/signUp">회원가입</a>

.
.
.

    </footer>

    <%-- session에 message 속성이 존재하는 경우 alert창으로 해당 내용을 출력 --%>

    <c:if test="${ !empty sessionScope.message }">

        <script>
            alert("${message}");

            // EL 작성 시 scope를 지정하지 않으면
            // page -> request -> session -> application 순서로 검색하여
            // 일치하는 속성이 있으면 출력
        </script>

        <%-- message 1회 출력 후 session에서 제거 --%>
        <c:remove var="message" scope="session"/>

    </c:if>
</body>
</html>

🔎 signUp.jsp

<%@ 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>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>KH 커뮤니티</title>

    <link rel="stylesheet" href="../resources/css/main-style.css">

    <link rel="stylesheet" href="../resources/css/signUp-style.css">
    
    <script src="https://kit.fontawesome.com/4dca1921b4.js" crossorigin="anonymous"></script>
</head>
<body>

    <main>
        <header>
            
            <!-- 클릭 시 메인페이지로 이동하는 로고 -->
            <section>
                <a href="#">
                    <img src="../resources/images/logo.jpg" id="home-logo">
                </a>
            </section>

            <!-- header의 두번째 자식 div -->
            <section>
                <article class="search-area">

                    <!-- form 내부 input 태그 값을 서버 또는 페이지로 전달 -->
                    <form action="#" name="search form">

                        <!-- fieldset : form 내부에서 input을 종류별로 묶는 용도로 많이 사용 -->
                        <fieldset>

                            <input type="search" id="query" name="query" 
                                placeholder="검색어를 입력해주세요" autocomplete="off">

                            <!-- 검색 버튼 -->
                            <button type="submit" id="search-btn" class="fa-solid fa-magnifying-glass"></button>
                            
                        </fieldset>

                    </form>
                </article>
            </section>
            <section></section>
        </header>

        <nav>

            <ul>
                <li><a href=#>공지사항</a></li>
                <li><a href=#>자유 게시판</a></li>
                <li><a href=#>질문 게시판</a></li>
                <li><a href=#>FAQ</a></li>
                <li><a href=#>1:1문의</a></li>
            </ul>
        </nav>

        <!-- 회원가입 -->
        <section class="signUp-content">

            <!-- 회원가입 화면 전환 주소(GET)와 같은 주소로
                 실제 회원가입을 요청(POST)
                 -> 요청 주소가 같아도 데이터 전달 방식이 다르면 중복 허용
            -->


            <!-- 절대경로 : /community/member/signUp

                 현재주소 : /community/member/signUp
                 상대경로 : signUp
            
            -->

            <form action="signUp" method="post" name="signUp-form">

                <label for="memberEmail">
                    <span class="required">*</span> 아이디(이메일)
                </label>

                <div class="signUp-input-area">
                    <input type="text" id="memberEmail" name="memberEmail"
                            placeholder="아이디(이메일)" maxlength="30"
                            autocomplete="off" required>

                    <!-- autocomplete="off" : 자동 완성 미사용 -->
                    <!-- required : 필수 작성 input 태그 -->

                    <button type="button">인증번호 받기</button>
                </div>

                <span class="signUp-message">메일을 받을 수 있는 이메일을 입력해 주세요.</span>

                <label for="emailCheck">
                    <span class="required">*</span> 인증번호
                </label>

                <div class="signUp-input-area">
                    <input type="text" id="emailCheck"
                            placeholder="인증번호 입력" maxlength="6"
                            autocomplete="off">

                    <button type="button">인증하기</button>
                </div>

                <span class="signUp-message confirm">인증되었습니다.</span>


                <label for="memberPw">
                    <span class="required">*</span> 비밀번호
                </label>

                <div class="signUp-input-area">
                    <input type="password" id="memberPw" name="memberPw"
                            placeholder="비밀번호" maxlength="30">
                </div>

                <div class="signUp-input-area">
                    <input type="password" id="memberPwConfirm"
                            placeholder="비밀번호 확인" maxlength="30">
                </div>

                <span class="signUp-message error">비밀번호가 일치하지 않습니다.</span>

                <label for="memberNickname">
                    <span class="required">*</span> 닉네임
                </label>

                <div class="signUp-input-area">
                    <input type="text" id="memberNickname" name="memberNickname"
                            placeholder="닉네임" maxlength="10">
                </div>

                <span class="signUp-message confirm">사용 가능한 닉네임입니다.</span>

                <label for="memberTel">
                    <span class="required">*</span> 전화번호
                </label>

                <div class="signUp-input-area">
                    <input type="text" id="memberTel" name="memberTel"
                            placeholder="(- 없이 숫자만 입력)" maxlength="11">
                </div>

                <span class="signUp-message error">전화번호 형식이 올바르지 않습니다.</span>

                <label for="memberAddress">
                    주소
                </label>

                <div class="signUp-input-area">
                    <input type="text" id="memberAddress" name="memberAddress"
                            placeholder="우편번호" maxlength="6">

                    <button type="button">검색</button>
                </div>

                <div class="signUp-input-area">
                    <input type="text" name="memberAddress" placeholder="도로명주소">
                </div>

                <div class="signUp-input-area">
                    <input type="text" name="memberAddress" placeholder="상세주소">
                </div>

                <button type="submit" id="signUp-btn">가입하기</button>

            </form>

        </section>

    </main>
    <footer>
        <p>Copyright &copy; KH Information Educational Institute M-Class</p>

        <article>
            <a href="#">프로젝트 소개</a>
            <span>|</span>
            <a href="#">이용약관</a>
            <span>|</span>
            <a href="#">개인정보처리방침</a>
            <span>|</span>
            <a href="#">고객센터</a>
        </article>
    </footer>

</body>
</html>

🔎 signUp-style.css

/* 회원가입 영역 */
.signUp-content{
    display: flex;
    justify-content: center;
}

/* 필수 */
.required{
    color: red;
    padding: 0 5px;
}

/* 회원가입 폼 */
form[name="signUp-form"]{
    margin-top: 30px;
}

/* 회원가입 폼 내부 input 제목(label) */
form[name="signUp-form"] > label{
    display: block;
    margin-top: 40px;
    font-size: 18px;
}

/* input을 감싸고 있는 div */
.signUp-input-area{
    width: 500px;
    height: 50px;
    margin-bottom: 10px;
    border-bottom: 2px solid #ddd;
    
    display: flex;
    align-items: center; /* 세로 중앙 */
}

/* input에 포커스가 맞춰졌을 때 밑줄 색 변화 */
/* :focus-within : 내부 input에 포커스가 맞춰졌을 때 */
.signUp-input-area:focus-within{
    border-bottom: 2px solid #455ba8;
}

/* input 태그 */
.signUp-input-area > input{
    width: 70%;
    height: 100%;
    padding: 15px 10px 5px; /* 상, 좌우, 하 */

    font-size: 16px;
    font-weight: bold;

    border: 0;
    outline: 0; /* input 선택 시 테두리 */
}

/* button 태그 */
.signUp-input-area > button{
    width: 30%;
    height: 70%;

    background-color: white;
    border: 1px solid gray;

    cursor: pointer;
}

/* 회원가입 관련 메시지 */
.signUp-messsage{
    font-size: 14px;
    letter-spacing: -1px; /* 자간 */
}

.confirm{ color: green;}
.error{ color: red;}

/* 가입하기 버튼 */
#signUp-btn{
    width: 100%;
    padding: 10px;
    margin: 50px 0;
    border: 0;

    font-size: 20px;
    font-weight: bold;

    color: white;
    background-color: #455ba8;

    cursor: pointer;
}

💡 Eclipse

🔎 SignUpServlet.java

package edu.kh.community.member.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;
import javax.servlet.http.HttpSession;

import org.apache.catalina.connector.Response;
import org.apache.catalina.tribes.util.Arrays;

import edu.kh.community.member.model.service.MemberService;
import edu.kh.community.member.model.vo.Member;

@WebServlet("/member/signUp")
public class SignUpServlet extends HttpServlet{
	
	// GET 방식 요청 시 JSP로 바로 응답할 수 있도록 요청 위임
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		String path = "/WEB-INF/views/member/signUp.jsp";
		req.getRequestDispatcher(path).forward(req, resp);

	}
	
	// POST 방식 요청 시 회원가입 서비스 수행
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		// 파라미터 모두 변수에 저장
		String memberEmail = req.getParameter("memberEmail");
		String memberPw = req.getParameter("memberPw");
		String memberNickname = req.getParameter("memberNickname");
		String memberTel = req.getParameter("memberTel");
	
		// 주소는 3개의 input으로 이루어져 있으므로 배열로 전달받음
		// -> DB 컬럼은 1개이므로 배열을 하나의 문자열로 합칠 예정
		String[] address = req.getParameterValues("memberAddress");

		
		// 주소가 입력되지 않으면 null이 아니라 빈칸 3개
		String memberAddress = null;
		
		if(!address[0].equals("")) { // 우편번호가 빈칸이 아니라면 == 주소 작성
			memberAddress = String.join(",,", address);
			
			// String.join("구분자", 배열)
			// -> 배열 요소를 하나의 문자열로 반환
			//	  요소 사이에 "구분자" 추가
		}
		
		// 파라미터를 하나의 Member 객체에 저장
		Member mem = new Member();
		
		mem.setMemberEmail(memberEmail);
		mem.setMemberPw(memberPw);
		mem.setMemberNickname(memberNickname);
		mem.setMemberTel(memberTel);
		mem.setMemberAddress(memberAddress);
		
		try {
			
			MemberService service = new MemberService();
			
			// 회원가입 서비스 호출 후 결과 반환 받기
			int result = service.signUp(mem);
			
			// 서비스 결과에 따라서 message를 다르게 하여 메인 페이지 재요청(redirect)
			
			HttpSession session = req.getSession();
			
			if(result > 0) { // 성공
				session.setAttribute("message", "회원 가입 성공!!");
				
			} else { // 실패
				session.setAttribute("message", "회원 가입 실패...");
			}
			
			resp.sendRedirect( req.getContextPath() );
			
		} catch(Exception e) {
			e.printStackTrace();
		}
		
	}
}

🔎 memberService.java


.
.
.
	/** 회원가입 Service
	 * @param mem
	 * @return result
	 * @throws Exception
	 */
	public int signUp(Member mem) throws Exception {
		
		// 1) 커넥션 얻어오기
		Connection conn = getConnection(); // DBCP에서 얻어옴
		
		// 2) DAO 메소드 호출 후 결과 반환 받기
		int result = dao.signUp(conn, mem);
		
		// 3) 트랜잭션 처리
		// result가 0인 경우 -> DAO return 구문 잘못 작성
		if(result > 0) conn.commit();
		else    	   conn.rollback();
		
		// 4) conn 반환(DBCP로 돌려주기)
		close(conn);
		
		// 5) 결과 반환
		return result;
	}
.
.
.

🔎 memberDAO.java


.
.
.
	/** 회원가입 DAO
	 * @param conn
	 * @param mem
	 * @return result
	 * @throws Exception
	 */
	public int signUp(Connection conn, Member mem) throws Exception{
	
		int result = 0; // 결과 저장용 변수
		
		try {
			
			String sql = prop.getProperty("signUp");
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, mem.getMemberEmail());
			pstmt.setString(2, mem.getMemberPw());
			pstmt.setString(3, mem.getMemberNickname());
			pstmt.setString(4, mem.getMemberTel());
			pstmt.setString(5, mem.getMemberAddress());
			
			result = pstmt.executeUpdate();
			
		} finally {
			
			close(pstmt);
			
		}
		
		// 결과 반환
		return result;
	}
.
.
.

🔎 member-sql.xml

.
.
.

	<!-- 회원가입 -->
	<entry key="signUp">
		INSERT INTO MEMBER
		VALUES(SEQ_MEMBER_NO.NEXTVAL, ?, ?, ?, ?, ?, DEFAULT, DEFAULT, DEFAULT)
	</entry>
    
.
.
.

profile
풀스택 개발자 기록집 📁

0개의 댓글