Search

νšŒμ›κ°€μž…

νšŒμ›κ°€μž…

β€’
κΈ°λŠ₯ μ„€λͺ…
β€’
μž‘μ—… μˆœμ„œ
β€’
μ‹€μŠ΅ μ½”λ“œ
β€’
ν…ŒμŠ€νŠΈ
β€’
κ²°κ³Ό ν™”λ©΄
(κ²°κ³Ό ν™”λ©΄ 사진)

κΈ°λŠ₯ μ„€λͺ…

νšŒμ› κ°€μž… κΈ°λŠ₯은 μ‚¬μš©μžμ˜ 정보λ₯Ό ν•΄λ‹Ή μ‚¬μ΄νŠΈ(μ„œλ²„)에 μ €μž₯ν•˜λŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€. - μ‚¬μš©μžλŠ” ν™”λ©΄μ—μ„œ μ‚¬μš©μž 정보(아이디, λΉ„λ°€λ²ˆν˜Έ λ“±)을 μž…λ ₯ν•©λ‹ˆλ‹€. - μ‚¬μš©μž 정보와 ν•¨κ»˜ μ„œλ²„μ— κ°€μž… μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€. - μ„œλ²„μ—μ„œλŠ” μ‚¬μš©μžμ˜ 정보λ₯Ό DB 에 μ €μž₯ ν›„, μ‘λ‹΅ν•©λ‹ˆλ‹€.
β€’
νšŒμ› κ°€μž… ν™”λ©΄
β€’
μœ νš¨μ„± 검사
β€’
νšŒμ› κ°€μž… μš”μ²­
β€’
νšŒμ› κ°€μž… 처리
β€’
νšŒμ› κ°€μž… 처리 ν›„ 응닡

νšŒμ› κ°€μž… ν™”λ©΄

μ‚¬μš©μžκ°€ κ°€μž… 정보λ₯Ό μž…λ ₯ν•˜λŠ” ν™”λ©΄μž…λ‹ˆλ‹€.

μœ νš¨μ„± 검사

μ‚¬μ΄νŠΈμ˜ 정책에 따라, 아이디, λΉ„λ°€λ²ˆν˜Έ λ“± μœ νš¨ν•œ κ°’λ§Œ μž…λ ₯이 κ°€λŠ₯ν•˜λ„λ‘ κ²€μ‚¬ν•˜λŠ” κ³Όμ •μž…λ‹ˆλ‹€.
β€’
null 체크
β€’
아이디 쀑볡 검사
β€’
λΉ„λ°€λ²ˆν˜Έ 쑰건 검사
β€’
이메일 ν˜•μ‹ 검사

null 체크

값을 μž…λ ₯ν•˜μ§€ μ•Šμ•„μ„œ, null, β€œβ€(빈 λ¬Έμžμ—΄) 등이 μ„œλ²„λ‘œ μš”μ²­λ˜μ§€ μ•Šλ„λ‘ ν™•μΈν•©λ‹ˆλ‹€.
null, β€œβ€(빈 λ¬Έμžμ—΄) 등이 μ„œλ²„λ‘œ μš”μ²­λ˜λ©΄, NullPointerException 등이 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
function checkNull(value) { return (value === null || value.trim() === ''); }
JavaScript
볡사
null 및 β€œβ€(빈 λ¬Έμžμ—΄) μ²΄ν¬λŠ” 자주 μ‚¬μš©λ˜λŠ” 쑰건으둜 곡톡 ν•¨μˆ˜λ‘œ μ •μ˜ν•˜μ—¬ μž¬μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

아이디 쀑볡 검사

μ•„μ΄λ””λŠ” κ³ μœ ν•œ κ°’μž…λ‹ˆλ‹€. DB μ—μ„œλ„ κΈ°λ³Έν‚€(PK), κ³ μœ ν‚€(UK) λ“±μœΌλ‘œ μ§€μ •ν•˜κΈ° λ•Œλ¬Έμ—, 이미 μžˆλŠ” 아이디가 μš”μ²­λœλ‹€λ©΄ μ„œλ²„ μΈ‘μ—μ„œ μ—λŸ¬κ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
μ€‘λ³΅λœ 아이디λ₯Ό μš”μ²­ν•˜κ²Œ 되면, λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 무결성 μ œμ•½ 쑰건에 μœ„λ°°λ  수 μžˆμŠ΅λ‹ˆλ‹€.
(아이디 쀑볡 검사 ν™”λ©΄)
아이디 쀑볡 κ²€μ‚¬λŠ” 비동기 처리λ₯Ό 톡해 κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 아이디 쀑볡 검사에 λŒ€ν•˜μ—¬ 동기식 form μš”μ²­μ„ ν•˜κ²Œ 되면 ν™”λ©΄ 이동을 ν•˜λ©΄μ„œ μž…λ ₯ν•œ 정보가 μ‚¬λΌμ§€κ±°λ‚˜ μš”μ²­μ„ μ—¬λŸ¬ 화면에 κ±Έμ³μ„œ μ§„ν–‰ν•΄μ•Όν•©λ‹ˆλ‹€.
λ”°λΌμ„œ, 아이디 쀑볡 κ²€μ‚¬λŠ” ν™”λ©΄ 이동 없이 비동기 μš”μ²­μ„ 보내어 쀑볡 여뢀에 λŒ€ν•œ 응닡 데이터λ₯Ό 받아와 κ·Έ μ—¬λΆ€λ₯Ό UI 및 검사 여뢀에 ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€.
β€’
아이디 쀑볡 검사 λ²„νŠΌ
<button type="button" onclick="clickIdCheck()" class="btn btn-success col-md-2">쀑볡확인</button>
HTML
볡사
β€’
아이디 쀑볡 검사 비동기 처리
// 아이디 쀑볡 확인 function idCheck() { let username = document.getElementById('username').value let url = `${root}/users/idCheck` let data = { 'username' : username, } return new Promise((resolve, reject) => { // jQuery 둜 AJAX μš”μ²­ $.ajax({ type : 'GET', // μš”μ²­ λ©”μ†Œλ“œ url : url, // μš”μ²­ URL data : data, // μš”μ²­ 데이터 contentType : 'application/json', // μš”μ²­ 데이터 νƒ€μž… dataType : 'html', // 응닡 데이터 νƒ€μž… // μš”μ²­ 성곡 success : function(response, status) { // response : 응닡 데이터 // status : 응닡 μƒνƒœ if( response == '' ) { alert('응닡 λ©”μ‹œμ§€κ°€ μ—†μŠ΅λ‹ˆλ‹€') } resolve(response == 'true' ? true : false) }, // μ—λŸ¬ error : function(xhr, status) { // xhr : XMLHttpRequest 객체 // status : 응닡 μƒνƒœ alert('μ—λŸ¬ λ°œμƒ') reject('error') } }) }) }
JavaScript
볡사

λΉ„λ°€λ²ˆν˜Έ 쑰건 검사

λΉ„λ°€λ²ˆν˜ΈλŠ” μ‚¬μ΄νŠΈμ˜ λ³΄μ•ˆ 정책에 λ”°λ₯Έ νŒ¨ν„΄μ— λ§€ν•‘λ˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€. 예λ₯Ό λ“€λ©΄, 8 자 μ΄μƒμ˜ 영문자, 숫자, 특수 문자λ₯Ό λͺ¨λ‘ ν¬ν•¨ν•˜λŠ” 지λ₯Ό κ²€μ‚¬ν•©λ‹ˆλ‹€.
μ΄λ ‡κ²Œ μ‘°κ±΄μ΄λ‚˜ νŒ¨ν„΄μ΄ λ³΅μž‘ν•œ μœ νš¨μ„±μ„ κ²€μ‚¬ν•˜λŠ” κ²½μš°μ—λŠ” μ •κ·œ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.
μ •κ·œν‘œν˜„μ‹μ΄λž€? : νŠΉμ • νŒ¨ν„΄μ„ μ°Ύκ±°λ‚˜ λ§€μΉ­ν•˜κΈ° μœ„ν•œ λ¬Έμžμ—΄μ˜ 집합을 μ •μ˜ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” ν˜•μ‹ μ–Έμ–΄
μ •κ·œ ν‘œν˜„μ‹μ— λŒ€ν•˜μ—¬λŠ” μ•„λž˜ νŽ˜μ΄μ§€μ—μ„œ 쑰금 더 μƒμ„Ένžˆ 닀루고 μžˆμŠ΅λ‹ˆλ‹€.
β€’
μ •κ·œ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜μ—¬ λΉ„λ°€λ²ˆν˜Έ μœ νš¨μ„± 검사
// λΉ„λ°€λ²ˆν˜Έ μœ νš¨μ„± 검사 let passwordCheck = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/ msg = 'λΉ„λ°€λ²ˆν˜ΈλŠ” 영문자, 숫자, 특수문자λ₯Ό ν¬ν•¨ν•˜μ—¬ 8자 μ΄μƒμœΌλ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”.' if (!check(passwordCheck, password, msg)) return false
JavaScript
볡사

이메일 ν˜•μ‹ 검사

이메일 ν˜•μ‹μ΄ μ˜¬λ°”λ₯Έμ§€ μ •κ·œ ν‘œν˜„μ‹μ„ μ΄μš©ν•˜μ—¬ κ²€μ‚¬ν•©λ‹ˆλ‹€.
μ‚¬μš©μžμ˜ κ°€μž… μ •λ³΄λ‘œ 이메일을 많이 μ‚¬μš©ν•˜λŠ”λ°, λ•Œλ‘œλŠ” μ΄λ©”μΌλ‘œ 인증 번호 λ˜λŠ” 링크λ₯Ό λ°œμ†‘ν•˜μ—¬ μ‚¬μš©μž μΈμ¦μ΄λ‚˜ λΉ„λ°€λ²ˆν˜Έ μ°ΎκΈ° κΈ°λŠ₯ λ“±κ³Ό μ—°λ™ν•˜λŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€.
이 λ•Œ, 이메일 ν˜•μ‹μ΄ μ˜¬λ°”λ₯΄μ§€ μ•Šλ‹€λ©΄, 이메일이 λ°œμ†‘λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ 이메일 ν˜•μ‹ νŒ¨ν„΄μ΄ μ˜¬λ°”λ₯Έμ§€ κ²€μ‚¬ν•˜μ—¬ μž…λ ₯ λ°›μŠ΅λ‹ˆλ‹€. 이메일 ν˜•μ‹μ€ OOOO@OOOO.com 이와 같은 νŒ¨ν„΄μœΌλ‘œ λ‹€μ†Œ λ³΅μž‘ν•œ ν˜•μ‹μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€.
이메일 ν˜•μ‹μ€ μ •κ·œ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜λ©΄ μ‰½κ²Œ 검사할 수 μžˆμŠ΅λ‹ˆλ‹€.
// 이메일 μœ νš¨μ„± 검사 let emailCheck = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i msg = '이메일 ν˜•μ‹μ΄ μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.' if (!check(emailCheck, email, msg)) return false
JavaScript
볡사

νšŒμ› κ°€μž… μš”μ²­

μž…λ ₯ν•œ 데이터가 λͺ¨λ‘ μœ νš¨ν•œμ§€ 검사 ν›„, POST λ°©μ‹μœΌλ‘œ form μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.
μ„œλ²„ μΈ‘μ—μ„œ μž…λ ₯ν•œ 데이터에 λŒ€ν•œ 이름은 input νƒœκ·Έμ˜ name 속성 κ°’μœΌλ‘œ μΈμ‹ν•©λ‹ˆλ‹€.
GET λ°©μ‹μœΌλ‘œ μ£Όμš” 데이터λ₯Ό μš”μ²­ν•˜κ²Œ 되면, URL 에 λ…ΈμΆœμ΄ λ˜λ―€λ‘œ λ³΄μ•ˆ 상 μœ„ν—˜ν•©λ‹ˆλ‹€.
name=β€νŒŒλΌλ―Έν„°λͺ…” κ³Ό request.getParameter(β€νŒŒλΌλ―Έν„°λͺ…”) 이 μΌμΉ˜ν•΄μ•Ό μš”μ²­ν•œ 값을, μ„œλ²„ μΈ‘μ—μ„œ μ •ν™•νžˆ 전달 받을 수 μžˆμŠ΅λ‹ˆλ‹€.
β€’
νšŒμ› κ°€μž… μš”μ²­ form
<form action="join_pro.jsp" name="joinForm" method="post"> <input type="hidden" name="duplicaed" id="duplicaed" value="false" /> <div class="input-group mb-3 row"> <label for="username" class="input-group-text col-md-4" id="lb_username">아이디</label> <input type="text" class="form-control col-md-6" name="username" id="username" placeholder="아이디" required> <button type="button" onclick="clickIdCheck()" class="btn btn-success col-md-2">쀑볡확인</button> </div> <div class="input-group mb-3 row"> <label for="password" class="input-group-text col-md-4" id="lb_password">λΉ„λ°€λ²ˆν˜Έ</label> <input type="password" class="form-control col-md-8" name="password" id="password" placeholder="λΉ„λ°€λ²ˆν˜Έ" required> </div> <div class="input-group mb-3 row"> <label for="password_confirm" class="input-group-text col-md-4" id="lb_password_confirm">λΉ„λ°€λ²ˆν˜Έ 확인</label> <input type="password" class="form-control col-md-8" name="password_confirm" id="password_confirm" placeholder="λΉ„λ°€λ²ˆν˜Έ 확인" required> </div> <div class="input-group mb-3 row"> <label for="name" class="input-group-text col-md-4" id="lb_name">이름</label> <input type="text" class="form-control col-md-8" name="name" id="name" placeholder="이름" required> </div> <div class="input-group mb-3 row"> <label for="email" class="input-group-text col-md-4" id="lb_email">이메일</label> <input type="text" class="form-control col-md-8" name="email" id="email" placeholder="이메일"> </div> <div class="d-grid gap-2 mt-5 mb-5 d-md-flex justify-content-md-between"> <a href="javascript: history.back()" class="btn btn-lg btn-secondary">μ·¨μ†Œ</a> <input type="button" class="btn btn-lg btn-primary" value="κ°€μž…" onclick="checkUser()" /> </div> </form>
HTML
볡사

νšŒμ› κ°€μž… 처리

ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ μš”μ²­ν•œ μ‚¬μš©μž 정보λ₯Ό 전달 λ°›κ³ , 이λ₯Ό 데이터 전솑 객체(DTO)에 λ‹΄μ•„ νšŒμ› κ°€μž… 처리 둜직으둜 μ „λ‹¬ν•©λ‹ˆλ‹€.
β€’
Servlet or JSP
β€’
DTO
β€’
Service
β€’
DAO

Servlet or JSP

νšŒμ› κ°€μž… ν™”λ©΄μ—μ„œ, μš”μ²­μ„ λ°›μ•„ μ²˜λ¦¬ν•  Servlet λ˜λŠ” JSP μ½”λ“œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€.
β€’
join_pro.jsp
<%-- νšŒμ› κ°€μž… 처리 --%> <%@page import="users.service.UserService"%> <%@page import="users.service.UserServiceImpl"%> <%@page import="users.model.Users"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% Users user = new Users(); String username = request.getParameter("username"); String password = request.getParameter("password"); String name = request.getParameter("name"); String email = request.getParameter("email"); user.setUsername(username); user.setPassword(password); user.setName(name); user.setEmail(email); // νšŒμ› 정보 등둝 μš”μ²­ UserService userService = new UserServiceImpl(); int result = userService.join(user); String root = request.getContextPath(); if( result > 0 ) { // 둜그인 ν™”λ©΄μœΌλ‘œ 이동 response.sendRedirect(root + "/users/login.jsp"); } else { // νšŒμ›κ°€μž… νŽ˜μ΄μ§€λ‘œ 이동 response.sendRedirect(root + "/users/join.jsp?error"); } %>
HTML
볡사

DTO

계측 간에, μ—¬λŸ¬ 데이터 λ‹΄μ•„ μ£Όκ³  받을 객체λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.
β€’
Users
package users.model; import java.util.Date; import lombok.Data; @Data public class Users { private String id; private String username; private String password; private String name; private String email; private Date regDate; private Date updDate; }
HTML
볡사

Service

처리 둜직(λΉ„μ¦ˆλ‹ˆμŠ€ 둜직)을 μž‘μ„±ν•©λ‹ˆλ‹€. - μΈν„°νŽ˜μ΄μŠ€μ™€ κ΅¬ν˜„ 클래슀둜 μ •μ˜ν•©λ‹ˆλ‹€.
β€’
UserService
β€’
UserServiceImpl
β€’
UserService
package users.service; import users.model.Users; public interface UserService { // νšŒμ›κ°€μž… public int join(Users user); // 아이디 쀑볡 확인 public boolean idCheck(String username); }
Java
볡사
β€’
UserServiceImpl
package users.service; import users.data.UserDAO; import users.model.Users; public class UserServiceImpl implements UserService { private UserDAO userDAO = new UserDAO(); /** * νšŒμ›κ°€μž… */ @Override public int join(Users user) { int result = userDAO.join(user); if( result > 0 ) { System.out.println("νšŒμ› κ°€μž… 처리 성곡!"); } else { System.out.println("νšŒμ› κ°€μž… μ‹€νŒ¨!"); } // κΈ°λ³Έ νšŒμ› κΆŒν•œμ„ μΆ”κ°€... return result; } /** * 아이디 쀑볡 확인 */ @Override public boolean idCheck(String username) { boolean result = userDAO.idCheck(username); return result; } }
Java
볡사

DAO

데이터 λ² μ΄μŠ€μ— μ ‘κ·Όν•˜λŠ” 객체둜, μ‚¬μš©ν•˜λŠ” DBMS μ—μ„œ μ œκ³΅ν•˜λŠ” JDBC λ“œλΌμ΄λ²„λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
β€’
UserDAO
package users.data; import java.sql.SQLException; import java.util.UUID; import common.jdbc.JDBConnection; import users.model.PersistentLogins; import users.model.Users; public class UserDAO extends JDBConnection { /** * νšŒμ› κ°€μž… * @param user 등둝할 νšŒμ› 정보 * @return λ“±λ‘λœ 데이터 개수 */ public int join(Users user) { int result = 0; String sql = "INSERT INTO users (id, username, password, name, email, reg_date, upd_date) " + "VALUES (RAWTOHEX(SYS_GUID()), ?, ?, ?, ?, sysdate, sysdate)"; try { psmt = con.prepareStatement(sql); psmt.setString(1, user.getUsername()); psmt.setString(2, user.getPassword()); psmt.setString(3, user.getName()); psmt.setString(4, user.getEmail()); result = psmt.executeUpdate(); } catch (SQLException e) { System.err.println("νšŒμ› κ°€μž… 쀑 였λ₯˜ λ°œμƒ"); e.printStackTrace(); } return result; } /** * 아이디 쀑볡 확인 * @param username * @return */ public boolean idCheck(String username) { // SQL μž‘μ„± String sql = " SELECT * " + " FROM users " + " WHERE username = ? "; try { psmt = con.prepareStatement(sql); psmt.setString( 1, username ); rs = psmt.executeQuery(); if( rs.next() ) { return true; // 아이디 쀑볡됨 } return false; } catch(SQLException e) { System.err.println("아이디 쀑볡 확인 μ‹œ, μ˜ˆμ™Έ λ°œμƒ"); e.printStackTrace(); } return false; } }
Java
볡사

νšŒμ› κ°€μž… 처리 ν›„ 응닡

νšŒμ› κ°€μž… μ™„λ£Œ 여뢀에 λ”°λΌμ„œ, νŽ˜μ΄μ§€ 응닡을 μ§„ν–‰ν•©λ‹ˆλ‹€.
β€’
νšŒμ› κ°€μž… 성곡
β€’
νšŒμ› κ°€μž… μ‹€νŒ¨

νšŒμ› κ°€μž… 성곡

νšŒμ› κ°€μž… 성곡 μ‹œ, νŽ˜μ΄μ§€λ₯Ό μ΄λ™μ‹œν‚΅λ‹ˆλ‹€.
νšŒμ› κ°€μž… 성곡 ν›„, 이동할 νŽ˜μ΄μ§€μ˜ μΌ€μ΄μŠ€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. κ°€μž… μ™„λ£Œ ν™”λ©΄ 둜그인 ν™”λ©΄ 메인 ν™”λ©΄
κ°€μž… μ™„λ£Œ ν™”λ©΄
과거의 UI/UX μ—μ„œλŠ” νšŒμ› κ°€μž… ν›„ λ‹€μ‹œ ν•œ 번 νšŒμ› κ°€μž… 정보 및 처리 여뢀에 λŒ€ν•΄μ„œ 좜λ ₯ν•˜λŠ” ν™”λ©΄μœΌλ‘œ μ΄λ™ν•˜κ³€ ν–ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜, κ°€μž… μ™„λ£Œ ν™”λ©΄μœΌλ‘œ μ΄λ™ν•˜λ”λΌλ„ λŒ€λ‹€μˆ˜μ˜ μ‚¬μš©μžλ“€μ€ λ°”λ‘œ λ‘œκ·ΈμΈμ„ μ‹œλ„ν•˜λ €κ³  ν•  κ²ƒμž…λ‹ˆλ‹€.
λ”°λΌμ„œ, κ°€μž… 정보 및 μ™„λ£Œ 여뢀에 λŒ€ν•˜μ—¬ λ°˜λ“œμ‹œ λ‹€μ‹œ λ¦¬ν¬νŠΈν•  ν•„μš”κ°€ μ—†λ‹€λ©΄, 둜그인 ν™”λ©΄ λ˜λŠ” 메인 ν™”λ©΄μœΌλ‘œ μ΄λ™ν•˜λŠ” 것이 더 λ‚˜μ€ μ‚¬μš©μž κ²½ν—˜μ„ μ œκ³΅ν•  κ²ƒμž…λ‹ˆλ‹€.
둜그인 ν™”λ©΄
νšŒμ› κ°€μž… ν›„, λŒ€λΆ€λΆ„μ˜ μ‚¬μš©μžλ“€μ€ λ°”λ‘œ λ‘œκ·ΈμΈμ„ μ‹œλ„ν•  κ²ƒμž…λ‹ˆλ‹€. λ”°λΌμ„œ νšŒμ› κ°€μž…μ΄ μ™„λ£Œλ˜μ—ˆλ‹€λ©΄ 둜그인 νŽ˜μ΄μ§€λ‘œ μ΄λ™μ‹œμΌœ, μ‚¬μš©μžκ°€ λ‘œκ·ΈμΈμ„ ν•  수 μžˆλ„λ‘ μœ λ„ν•©λ‹ˆλ‹€.
메인 ν™”λ©΄
μ‚¬μš©μžλŠ” λ‘œκ·ΈμΈμ„ ν•˜κΈ° μœ„ν•΄μ„œ νšŒμ› κ°€μž…μ„ μ§„ν–‰ν•˜μ˜€μ„ κ²ƒμž…λ‹ˆλ‹€. λ”°λΌμ„œ, μ‚¬μš©μžμ—κ²Œ νšŒμ› κ°€μž… μ‹œ μž…λ ₯ν•œ 아이디 및 λΉ„λ°€λ²ˆν˜Έλ₯Ό 또 μž…λ ₯ν•˜κ²Œ ν•˜λŠ” 것은 λ‹€μ†Œ 번거둜운 일이 될 수 μžˆμŠ΅λ‹ˆλ‹€. 이미 νšŒμ› κ°€μž… μ‹œ 아이디 및 λΉ„λ°€λ²ˆν˜Έλ₯Ό μž…λ ₯ν•˜μ˜€κΈ° λ•Œλ¬Έμ— μ„œλ²„ μΈ‘μ—μ„œ 둜그인 인증 처리 ν›„ 메인 화면에 둜그인 된 μƒνƒœλ‘œ μ‘λ‹΅ν•΄μ£ΌλŠ” 것도 쒋은 λ°©λ²•μž…λ‹ˆλ‹€,
νšŒμ› κ°€μž… 처리 성곡 λ°”λ‘œ 둜그인 메인 ν™”λ©΄
λ°”λ‘œ 둜그인 κΈ°λŠ₯의 경우, 둜그인 κΈ°λŠ₯을 κ΅¬ν˜„ ν›„ μ μš©ν•΄μ•Όν•©λ‹ˆλ‹€.

νšŒμ› κ°€μž… μ‹€νŒ¨

νšŒμ› κ°€μž… μ‹€νŒ¨ μ‹œ, νšŒμ› κ°€μž… 정보λ₯Ό λ‹€μ‹œ μž…λ ₯ν•˜λ„λ‘ ν•„μš”ν•œ λ©”μ‹œμ§€μ™€ ν•¨κ»˜ νšŒμ› κ°€μž… νŽ˜μ΄μ§€λ‘œ λ‹€μ‹œ μ΄λ™ν•©λ‹ˆλ‹€.
νšŒμ› κ°€μž… 처리 μ‹€νŒ¨ νšŒμ› κ°€μž… ν™”λ©΄

μž‘μ—… μˆœμ„œ

1.
νšŒμ› 정보 ERD μž‘μ„±
2.
users - νšŒμ› ν…Œμ΄λΈ” 생성
3.
common.jsp - 곡톡 적용 νŽ˜μ΄μ§€ μž‘μ„±
4.
join.jsp (νšŒμ›κ°€μž… ν™”λ©΄) νŽ˜μ΄μ§€ μž‘μ„±
5.
μœ νš¨μ„± 검사 μ½”λ“œ μž‘μ„±
6.
JDBConnection.java - JDBC λ“œλΌμ΄λ²„ 연동
7.
UserDAO.java - 데이터 μ ‘κ·Ό 객체 μž‘μ„±
8.
UserService.java - μ„œλΉ„μŠ€ μΈν„°νŽ˜μ΄μŠ€ μž‘μ„±
9.
UserServiceImpl.java - μ„œλΉ„μŠ€ κ΅¬ν˜„ 클래슀 μž‘μ„±
10.
join_pro.jsp (νšŒμ› κ°€μž… 처리) νŽ˜μ΄μ§€ μž‘μ„±

μ‹€μŠ΅ μ½”λ“œ

νšŒμ› 정보 ERD μž‘μ„±

users - νšŒμ› ν…Œμ΄λΈ” 생성

CREATE TABLE users ( id VARCHAR2(255) NOT NULL PRIMARY KEY, username VARCHAR2(100) NULL, password VARCHAR2(100) NULL, name VARCHAR2(50) NULL, email VARCHAR2(200) NULL, reg_date DATE DEFAULT sysdate NULL, upd_date DATE DEFAULT sysdate NULL );
SQL
볡사

common.jsp - 곡톡 적용 νŽ˜μ΄μ§€ μž‘μ„±

β€’
common.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% String root = request.getContextPath(); %> <c:set var="root" value="<%= root %>" />
Java
볡사
<%= request.getContextPath() %>
Java
볡사
μœ„ μ½”λ“œμ™€ 같이, 반볡적으둜 μ‚¬μš©λ˜λŠ” μ½”λ“œλ₯Ό 곡톡 λͺ¨λ“ˆ (common.jsp) 에 μ μš©ν•΄λ‘κ³  μ‚¬μš©ν•˜κ² μŠ΅λ‹ˆλ‹€.
μ΄λ ‡κ²Œ ContextPath λ₯Ό 미리 root λΌλŠ” λ³€μˆ˜λͺ…μœΌλ‘œ μ €μž₯해두면, link νƒœκ·Έ λ˜λŠ” script νƒœκ·Έμ—μ„œ ν•΄λ‹Ή 파일의 경둜λ₯Ό 지정할 λ•Œ μ•„λž˜μ™€ 같이 λ‹¨μˆœν•˜κ²Œ 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.
<jsp:include page="${ root }/layout/import/link.jsp" />
Java
볡사

join.jsp (νšŒμ›κ°€μž… ν™”λ©΄) νŽ˜μ΄μ§€ μž‘μ„±

νšŒμ› κ°€μž… ν™”λ©΄

β€’
join.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- 곡톡 적용 --> <jsp:include page="/layout/main/import/common.jsp" /> <jsp:include page="/layout/main/import/meta.jsp" /> <jsp:include page="/layout/main/import/link.jsp" /> </head> <body> <jsp:include page="/layout/main/UI/header.jsp" /> <div class="px-4 py-5 mt-5 text-center"> <h1 class="display-5 fw-bold text-body-emphasis">νšŒμ› κ°€μž…</h1> </div> <!-- νšŒμ› κ°€μž… μ˜μ—­ --> <div class="container shop p-5 mb-5" > <form action="join_pro.jsp" name="joinForm" method="post"> <input type="hidden" name="duplicaed" id="duplicaed" value="false" /> <div class="input-group mb-3 row"> <label for="username" class="input-group-text col-md-4" id="lb_username">아이디</label> <input type="text" class="form-control col-md-6" name="username" id="username" placeholder="아이디" required> <button type="button" onclick="clickIdCheck()" class="btn btn-success col-md-2">쀑볡확인</button> </div> <div class="input-group mb-3 row"> <label for="password" class="input-group-text col-md-4" id="lb_password">λΉ„λ°€λ²ˆν˜Έ</label> <input type="password" class="form-control col-md-8" name="password" id="password" placeholder="λΉ„λ°€λ²ˆν˜Έ" required> </div> <div class="input-group mb-3 row"> <label for="password_confirm" class="input-group-text col-md-4" id="lb_password_confirm">λΉ„λ°€λ²ˆν˜Έ 확인</label> <input type="password" class="form-control col-md-8" name="password_confirm" id="password_confirm" placeholder="λΉ„λ°€λ²ˆν˜Έ 확인" required> </div> <div class="input-group mb-3 row"> <label for="name" class="input-group-text col-md-4" id="lb_name">이름</label> <input type="text" class="form-control col-md-8" name="name" id="name" placeholder="이름" required> </div> <div class="input-group mb-3 row"> <label for="email" class="input-group-text col-md-4" id="lb_email">이메일</label> <input type="text" class="form-control col-md-8" name="email" id="email" placeholder="이메일"> </div> <div class="d-grid gap-2 mt-5 mb-5 d-md-flex justify-content-md-between"> <a href="javascript: history.back()" class="btn btn-lg btn-secondary">μ·¨μ†Œ</a> <input type="button" class="btn btn-lg btn-primary" value="κ°€μž…" onclick="checkUser()" /> </div> </form> </div> <jsp:include page="/layout/main/UI/footer.jsp" /> <!-- script --> <jsp:include page="/layout/main/import/script.jsp" /> <script> async function clickIdCheck() { let check = await idCheck() if( check ) { alert('μ€‘λ³΅λœ 아이디 μž…λ‹ˆλ‹€.') } else { alert('μ‚¬μš© κ°€λŠ₯ν•œ 아이디 μž…λ‹ˆλ‹€.') } } </script> </body> </html>
HTML
볡사

μœ νš¨μ„± 검사 μ½”λ“œ μž‘μ„±

+아이디 쀑볡 검사
β€’
script.js
/** * javascript - script.js */ /** * νšŒμ› κ°€μž… - μœ νš¨μ„± 검사 */ async function checkUser() { let form = document.joinForm // 아이디 쀑볡 확인 let idDuplicated = await idCheck() if( idDuplicated ) { alert('μ€‘λ³΅λœ 아이디 μž…λ‹ˆλ‹€.') return false } if( validateUser() ) { form.submit() // μœ νš¨μ„± 검사 톡과 return true } } function validateUser() { let form = document.joinForm let username = form.username let password = form.password let password_confirm = form.password_confirm let name = form.name let email = form.email let msg = '' // 아이디 μœ νš¨μ„± 검사 let usernameCheck = /^[a-zA-Z0-9γ„±-γ…Žγ…-γ…£κ°€-힣]{5,20}$/ msg = 'μ•„μ΄λ””λŠ” ν•œκΈ€, 영문자, 숫자 5~20 자둜 μž…λ ₯ν•΄μ£Όμ„Έμš”.' if (!check(usernameCheck, username, msg)) return false // λΉ„λ°€λ²ˆν˜Έ μœ νš¨μ„± 검사 let passwordCheck = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/ msg = 'λΉ„λ°€λ²ˆν˜ΈλŠ” 영문자, 숫자, 특수문자λ₯Ό ν¬ν•¨ν•˜μ—¬ 8자 μ΄μƒμœΌλ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”.' if (!check(passwordCheck, password, msg)) return false // λΉ„λ°€λ²ˆν˜Έ 확인 검사 msg = 'λΉ„λ°€λ²ˆν˜Έμ™€ λΉ„λ°€λ²ˆν˜Έ 확인이 λΆˆμΌμΉ˜ν•©λ‹ˆλ‹€.' if( password.value != password_confirm.value ) { alert(msg) return false } // 이름 μœ νš¨μ„± 검사 let nameCheck = /^[a-zA-Zγ„±-γ…Žγ…-γ…£κ°€-힣]{1,20}$/ msg = '이름은 ν•œκΈ€ λ˜λŠ” 영문 20자 μ΄λ‚΄λ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”.' if (!check(nameCheck, name, msg)) return false // 이메일 μœ νš¨μ„± 검사 let emailCheck = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i msg = '이메일 ν˜•μ‹μ΄ μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.' if (!check(emailCheck, email, msg)) return false return true } // μ •κ·œν‘œν˜„μ‹ μœ νš¨μ„± 검사 ν•¨μˆ˜ function check(regExp, element, msg) { if(regExp.test(element.value)) { return true } alert(msg) element.select() element.focus() return false } // 아이디 쀑볡 확인 function idCheck() { let username = document.getElementById('username').value let url = `${root}/users/idCheck` let data = { 'username' : username, } return new Promise((resolve, reject) => { // jQuery 둜 AJAX μš”μ²­ $.ajax({ type : 'GET', // μš”μ²­ λ©”μ†Œλ“œ url : url, // μš”μ²­ URL data : data, // μš”μ²­ 데이터 contentType : 'application/json', // μš”μ²­ 데이터 νƒ€μž… dataType : 'html', // 응닡 데이터 νƒ€μž… // μš”μ²­ 성곡 success : function(response, status) { // response : 응닡 데이터 // status : 응닡 μƒνƒœ if( response == '' ) { alert('응닡 λ©”μ‹œμ§€κ°€ μ—†μŠ΅λ‹ˆλ‹€') } resolve(response == 'true' ? true : false) }, // μ—λŸ¬ error : function(xhr, status) { // xhr : XMLHttpRequest 객체 // status : 응닡 μƒνƒœ alert('μ—λŸ¬ λ°œμƒ') reject('error') } }) }) }
JavaScript
볡사

JDBConnection.java - JDBC λ“œλΌμ΄λ²„ 연동

β€’
JDBConnection.java
package common.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; public class JDBConnection { public Connection con; // μ—°κ²°λœ λ“œλΌμ΄λ²„μ— SQL을 μš”μ²­ν•  객체λ₯Ό μƒμ„±ν•˜λŠ” 클래슀 public Statement stmt; // SQL μ‹€ν–‰ μš”μ²­μ„ ν•˜λŠ” 클래슀 public PreparedStatement psmt; // Statement μ—μ„œ ? νŒŒλΌλ―Έν„° ν™•μž₯κΈ°λŠ₯을 μΆ”κ°€λ‘œ μ œκ³΅ν•˜λŠ” 클래슀 public ResultSet rs; // SQL μ‹€ν–‰ κ²°κ³Όλ₯Ό λ°›μ•„μ˜€λŠ” 클래슀 // κΈ°λ³Έ μƒμ„±μž public JDBConnection() { // JDBC λ“œλΌμ΄λ²„ λ‘œλ“œ // Oracle try { // ojdbc8.jar λ“œλΌμ΄λ²„μ˜ 클래슀λ₯Ό λ‘œλ“œν•œλ‹€. Class.forName("oracle.jdbc.OracleDriver"); // DB에 μ—°κ²° // jdbc:oracle:thin - JDBC λ“œλΌμ΄λ²„ νƒ€μž… (thin νƒ€μž…) // localhost - 호슀트 μ£Όμ†Œ (IP μ£Όμ†Œ), localhost λ˜λŠ” 127.0.0.1 은 ν˜„μž¬ PC의 IP λ₯Ό 가리킨닀. // :1521 - 포트번호 (1521은 였라클 DBμ„œλ²„μ˜ κΈ°λ³Έ 포트 λ²ˆν˜Έμ΄λ‹€.) // :xe λ˜λŠ” :orcl - SID (μ„œλΉ„μŠ€ ID) //String url ="jdbc:oracle:thin:@localhost:1521:xe"; // 11g // String url ="jdbc:oracle:thin:@localhost:1521:orcl"; // 12c이상 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String id = "aloha"; String pw = "123456"; // μžλ°” ν”„λ‘œκ·Έλž¨μ—μ„œ JDBC λ“œλΌμ΄λ²„λ₯Ό μ—°κ²°μ‹œμΌœμ£ΌλŠ” 클래슀 // getConnection() λ©”μ†Œλ“œλ‘œ DB에 μ—°κ²° μš”μ²­ν•˜κ³  μƒμ„±λœ Connection 객체λ₯Ό λ°˜ν™˜λ°›λŠ”λ‹€. con = DriverManager.getConnection(url, id, pw); // System.out.println("DB μ—°κ²° 성곡"); } catch (Exception e) { System.err.println("DB μ—°κ²° μ‹€νŒ¨"); e.printStackTrace(); } } }
Java
볡사

UserDAO.java - 데이터 μ ‘κ·Ό 객체 μž‘μ„±

β€’
UserDAO.java
package users.data; import java.sql.SQLException; import java.util.UUID; import common.jdbc.JDBConnection; import users.model.PersistentLogins; import users.model.Users; public class UserDAO extends JDBConnection { /** * νšŒμ› κ°€μž… * @param user 등둝할 νšŒμ› 정보 * @return λ“±λ‘λœ 데이터 개수 */ public int join(Users user) { int result = 0; String sql = "INSERT INTO users (id, username, password, name, email, reg_date, upd_date) " + "VALUES (RAWTOHEX(SYS_GUID()), ?, ?, ?, ?, sysdate, sysdate)"; try { psmt = con.prepareStatement(sql); psmt.setString(1, user.getUsername()); psmt.setString(2, user.getPassword()); psmt.setString(3, user.getName()); psmt.setString(4, user.getEmail()); result = psmt.executeUpdate(); } catch (SQLException e) { System.err.println("νšŒμ› κ°€μž… 쀑 였λ₯˜ λ°œμƒ"); e.printStackTrace(); } return result; } }
Java
볡사

UserService.java - μ„œλΉ„μŠ€ μΈν„°νŽ˜μ΄μŠ€ μž‘μ„±

β€’
UserService.java
package users.service; import users.model.Users; public interface UserService { // νšŒμ›κ°€μž… public int join(Users user); }
Java
볡사

UserServiceImpl.java - μ„œλΉ„μŠ€ κ΅¬ν˜„ 클래슀 μž‘μ„±

β€’
UserServiceImpl.java
package users.service; import users.data.UserDAO; import users.model.PersistentLogins; import users.model.Users; public class UserServiceImpl implements UserService { private UserDAO userDAO = new UserDAO(); @Override public int join(Users user) { int result = userDAO.join(user); if( result > 0 ) { System.out.println("νšŒμ› κ°€μž… 처리 성곡!"); } else { System.out.println("νšŒμ› κ°€μž… μ‹€νŒ¨!"); } return result; } }
Java
볡사

join_pro.jsp (νšŒμ› κ°€μž… 처리) νŽ˜μ΄μ§€ μž‘μ„±

β€’
join_pro.jsp
<%-- νšŒμ› κ°€μž… 처리 --%> <%@page import="users.service.UserService"%> <%@page import="users.service.UserServiceImpl"%> <%@page import="users.model.Users"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% Users user = new Users(); String username = request.getParameter("username"); String password = request.getParameter("password"); String name = request.getParameter("name"); String email = request.getParameter("email"); user.setUsername(username); user.setPassword(password); user.setName(name); user.setEmail(email); // νšŒμ› 정보 등둝 μš”μ²­ UserService userService = new UserServiceImpl(); int result = userService.join(user); String root = request.getContextPath(); if( result > 0 ) { // 둜그인 ν™”λ©΄μœΌλ‘œ 이동 response.sendRedirect(root + "/users/login.jsp"); } else { // νšŒμ›κ°€μž… νŽ˜μ΄μ§€λ‘œ 이동 response.sendRedirect(root + "/users/join.jsp?error"); } %>
Java
볡사

ν…ŒμŠ€νŠΈ

(좔가쀑)

κ²°κ³Ό ν™”λ©΄