JSP(ajax를 이용한 id중복검사, readOnly )

최동민·2022년 6월 28일
0

JSP

목록 보기
9/10

member.js

/**
 * 회원가입 유효성 검사
 */

var form = document.joinForm;

function join(){
	//value를 조건식 안에서 사용하면
	//값이 있을 때 true, 값이 없을 때 false
	if(!form.id.value){
		alert("아이디를 입력해주세요.");
		form.id.focus();
		return;
	}
	if(form.id.value.length < 4 || form.id.value.length > 16){
		alert("아이디는 4자 이상, 16자 이하로 입력해주세요.")
		form.id.focus();
		return;
	}
	if(!form.name.value){
		alert("이름을 입력해주세요.");
		form.name.focus();
		return;
	}
	if(!form.password.value){
		alert("비밀번호를 입력해주세요.");
		form.password.focus();
		return;
	}
	
	//8자리 이상, 대문자, 소문자, 숫자, 특수문자 모두 포함되어 있는 지 검사
	let reg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/;
	let hangleCheck = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/
	
	if(!reg.test(form.password.value)){
		alert("비밀번호는 8자리 이상이어야 하며, 대문자/소문자/숫자/특수문자 모두 포함해야 합니다.");
		form.password.focus();
		return;
	}
	
	//같은 문자를 4번 사용할 수 없다.
	if(/(\w)\1\1\1/.test(form.password.value)){
		alert("같은 문자를 4번 이상 사용하실 수 없습니다.");
		form.password.focus();
		return;
	}
	
	//비밀번호 안에 아이디가 있을 때
	if(form.password.value.search(form.id.value) != -1){
		alert("비밀번호에 아이디를 포함할 수 없습니다.");
		form.password.focus();
		return;
	}
	
	//비밀번호에 한글이 있으면 안된다.
	if(hangleCheck.test(form.password.value)){
		alert("비밀번호에 한글을 사용할 수 없습니다.");
		form.password.focus();
		return;
	}
	
	//비밀번호에 공백을 포함할 수 없다.
	if(form.password.value.search(/\s/) != -1){
		alert("비밀번호에 공백 없이 입력해주세요.");
		form.password.focus();
		return;
	}
	
	if(form.password.value != form.password_re.value){
		alert("비밀번호를 확인해주세요.");
		form.password.focus();
		return;
	}
	
	if(!form.id.readOnly){
		alert("아이디 중복 검사를 진행해주세요.");
		return;
	}
	form.submit();
}

$("input[name='id']").on("click", function(){
	form.id.readOnly = false;
})

function checkId(){
	var xhr = new XMLHttpRequest();
	
	xhr.open("GET", "join_ok.jsp?id=" + document.getElementById("id").value, true);
	xhr.send();
	
	xhr.onreadystatechange = function(){
		if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200){
			document.getElementById("result").innerHTML = xhr.responseText.trim();
			if(xhr.responseText.search("가능") != -1){
				form.id.readOnly = true;
			}
		}
	}
}

readOnly 가 true이면 아이디 검사가 잘되었다는 것. 중복검사가 잘되었다는 것.
false이면 중복 검사를 하지 않았거나, 중복 검사 후 수정하기 위해 변경했다거나.

아이디를 입력 후 중복검사를 하면 사용가능한 id라 나온다.
이 상태에서 아이디 창을 클릭하면 readOnly가 풀리고, 이 상태에서 회원가입 완료를 클릭하게 되면 '아이디 중복 검사를 진행해주세요' 라는 문구를 준다.

제대로 입력 후 회원가입 완료를 하면 login.jsp로 이동.
데이터베이스에 INSERT가 잘 되었다는 뜻이겠다.

사용자에게 입력 화면을 보여준 후 유효성 검사를 한다면 이렇게 js를 사용하면 되겠다.

자바스크립트 안에 있는 메서드(join())를 join.jsp에서 외부 자바스크립트로 추가해놓은 상태

<input type="button" onclick="join()" value="회원가입 완료">
<script src="member.js"></script>

member.js에 해당 html의 jsp에 포함이 되어있기 때문에 각각의 요소들의 DOM을 사용해 접근했다. 맨 처음 join전에는 많은 검사를 하다가 id 중복 검사를 checkId라는 걸 이용해 get방식으로 ajax를 사용했다.
현재 페이지 이동이 되지 않고 내가 원하는 부분에 DB 연산이 됨.

xhr.open("GET", "join_ok.jsp?id=" + document.getElementById("id").value, true);

따라서 이렇게 url을 보냈더니 여기에 대해서 join_ok에서는 전달받은 걸 useBean을 사용해 중복인지 아닌지를 검사했고, checkId가 true인지 fals인지에 따라서 알맞는 메시지가 바디 태그에 print 된다.
이 응답값을 다시 한번 member.js에서

			document.getElementById("result").innerHTML = xhr.responseText.trim();

responseText 로 받아주고 trim으로 앞뒤 공백을 제거.
그 값을 result라는 id를 가진 태그에다 집어넣었고, 만약 그 메시지에 '가능'이라는 문구가 있다면 들어와서 더 이상 수정할 수 없게끔 true로 만들어주었다.
하지만 내가 마음에 들지 않을 때 다시 수정할 수 있게끔 하기 위해 다시 한번 클릭하면 readOnly를 풀어준다. 이 상태에서 readOnly가 true/false 이냐에 따라 중복검사 여부가 나뉜다. 하지 않았다면 '아이디 중복 검사를 진행해주세요' 문구가 나오고, 전부 완성되었다면 submit을 통해 해당 폼 태그가 action으로 이동하게 되는 것. 결과적으로 join_db에서 검사하고 login.jsp까지 오게되는 것.

join_db.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean class="dao.UserDAO" id="dao"/>
<jsp:useBean class="vo.UserVO" id="vo"/>
<jsp:setProperty property="*" name="vo"/>

<%
	dao.join(vo);
	response.sendRedirect("login.jsp");
%>

join.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>
	<form action="join_db.jsp" method="post" name="joinForm">
		<p>
			<label>아이디 : <input type="text" name="id" id="id"></label>
			<input type="button" onclick="checkId()" value="중복 확인">
		</p>
		<p id="result"></p>
		<p><label>이름 : <input type="text" name="name"></label></p>
		<p><label>비밀번호 : <input type="password" name="password"></label></p>
		<p><label>비밀번호 확인 : <input type="password" name="password_re"></label></p>
		<p>
			성별 : 
			남자 <input type="radio" name="gender" value="남자" checked>
			여자 <input type="radio" name="gender" value="여자" checked>
		</p>
		<p>
			<label>
				우편번호 : 
				<input type="text" name="zipcode" class="postcodify_postcode5" value="" />
				<button type="button" id="postcodify_search_button">검색</button><br />
			</label>
		</p>
		<p>
			<label>
				주소 : 
				<input type="text" name="address" class="postcodify_address" value="" /><br />
			</label>
		</p>
		<p>
			<label>
				상세 주소 :
				<input type="text" name="address_detail" class="postcodify_details" value="" /><br />
			</label>
		</p>
		<p>
			<label>
				참고 항목 : 
				<input type="text" name="address_etc" class="postcodify_extra_info" value="" /><br />
			</label>
		</p>
		<input type="button" onclick="join()" value="회원가입 완료">
	</form>
</body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//d1p7wdleee1q2z.cloudfront.net/post/search.min.js"></script>
<script> $(function() { $("#postcodify_search_button").postcodifyPopUp(); }); </script>
<script src="member.js"></script>
</html>

DBConnecter
이 커넥션 객체를 쓰는 건 UserDAO가 되겠다

package dao;

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

public class DBConnecter {
	//DAO에서 모든 메소드에 필요한 DB연결 문법을 미리 메소드에 선언해 놓는다.
	public static Connection getconnection() {
		Connection conn = null;
		
		try {
			//DB연결을 위한 정보를 입력한다(url, username, password).
			String url = "jdbc:oracle:thin:@localhost:1521:XE";
			String user = "hr";
			String pw = "hr";
			
			//드라이버를 메모리에 할당한다.
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			//입력한 정보를 전달하여 드라이버를 통해 연결 객체를 가져온다.
			conn = DriverManager.getConnection(url, user, pw);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return conn;
	}
}

UserDAO

package dao;

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

import vo.UserVO;

//private int num;
//private String id;
//private String name;
//private String password;
//private String gender;
//private String zipcode;
//private String address;
//private String address_detail;
//private String address_etc;

public class UserDAO {

	Connection conn; //외부 저장소인 DBMS를 드라이버를 통해 가져온 연결 객체 
	PreparedStatement pstm; //문자열안에 있는 SQL문을 객체로 저장, 변수가 들어갈 자리에 알맞는 값을 넣어줌, SQL문 실행시킴
	ResultSet rs; //SELECT의 결과를 담는 객체
	
	public void join(UserVO user) {
		//SQL문 작성
		String query = "INSERT INTO TBL_USER VALUES(SEQ_USER.NEXTVAL, ?, ?, ?, ?, ?, ?, ?, ?)";
		
		try {
			//connection객체를 전달받는다.
			conn = DBConnecter.getconnection();
			//위에서 작성한 쿼리문을 prepareStatement에 전달한다.
			pstm = conn.prepareStatement(query);
			//?자리에 알맞는 변수를 전달해준다.
			pstm.setString(1, user.getId());
			pstm.setString(2, user.getName());
			pstm.setString(3, user.getPassword());
			pstm.setString(4, user.getGender());
			pstm.setString(5, user.getZipcode());
			pstm.setString(6, user.getAddress());
			pstm.setString(7, user.getAddress_detail());
			pstm.setString(8, user.getAddress_etc());
			
			//DML중 INSERT 쿼리를 실행하는 메소드를 사용한다.
			pstm.executeUpdate();//결과 건수
			
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(pstm != null) {
					pstm.close();
				}
				if(conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	//아이디 중복검사
	public boolean checkId(String id) {
		String query = "SELECT COUNT(ID) FROM TBL_USER WHERE ID = ?";
		boolean check = false;
		try {
			//DBMS 연결 객체 가져오기
			conn = DBConnecter.getconnection();
			//String으로 선언된 쿼리를 pstm객체에 전달하기
			pstm = conn.prepareStatement(query);
			//SQL 쿼리에 ?가 있다면 알맞는 값으로 지정해주기
			pstm.setString(1, id);
			//쿼리 실행 후 결과를 rs객체에 담기
			rs = pstm.executeQuery();
			
			//행가져오기
			rs.next();
			//위에서 가져온 행의 열을 타입에 맞춰서 가져오기
			check = rs.getInt(1) == 1;	//0일 때 중복 없음(false), 1일 때 중복 있음(true)
			
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs != null) {
					rs.close();
				}
				if(pstm != null) {
					pstm.close();
				}
				if(conn != null) {
					pstm.close();
				}
			} catch (SQLException e) {
				throw new RuntimeException(e);
			}
		}
		return check;
	}
}
profile
코드를 두드리면 문이 열린다

0개의 댓글