TIL 0513

먼지·2024년 5월 13일

Today I Learned

목록 보기
58/89
post-thumbnail

Member DAO - ID 중복 체크

zmember와 zmember_detial을 outer join 할 때 누락된 데이터가 보여져야 id 중복 체크가 가능하다.

// ID 중복 체크 및 로그인 처리
	public MemberVO checkMember(String id) throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		ResultSet rs = null;
		MemberVO member = null; 
		try {
			conn = DBUtil.getConnection();
			sql="SELECT * FROM zmember LEFT OUTER JOIN zmember_detail USING(mem_num) WHERE id=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			if(rs.next()) {
				member = new MemberVO();
				member.setMem_num(rs.getInt("mem_num"));
				member.setId(rs.getString("id"));
				member.setAuth(rs.getInt("auth"));
				member.setPasswd(rs.getString("passwd"));
				member.setPhoto(rs.getString("photo"));
				member.setEmail(rs.getString("email")); // 회원 탈퇴시에 필요한 정보
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			DBUtil.executeClose(rs, pstmt, conn);
		}
		return member;
	}

CheckDuplicatedIdAction

lib > jackson-core-asl-1.9.11.jar/jackson-mapper-asl-1.9.11.jar Copy 시켜놓기

JSON 형식으로 변환하기를 원하는 문자열을 HashMap에 key와 value의 쌍으로 지정한 후 ObjectMapper의 writeValueAsString에 Map 객체를 전달해서 일반 문자열 데이터를 JSON 형식의 문자열 데이터로 변환 후 반환한다

package kr.main.action;

import java.util.HashMap;
import java.util.Map;

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

import org.codehaus.jackson.map.ObjectMapper;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;

public class CheckDuplicatedIdAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 전송된 데이터 인코딩 타입 지정
		request.setCharacterEncoding("utf-8");
		
		// 전송된 데이터 반환
		String id = request.getParameter("id");
		
		MemberDAO dao = MemberDAO.getInstance();
		MemberVO member = dao.checkMember(id);
		
		Map<String, String> mapAjax = new HashMap<String, String>();
		
		if(member == null) { // 아이디 미중복
			mapAjax.put("result","idNotFound");
		} else { // 아이디 중복
			mapAjax.put("result", "idDuplicated");
		}

		ObjectMapper mapper = new ObjectMapper();
//		JSON 문자열 반환
		String ajaxData = mapper.writeValueAsString(mapAjax);
		
		request.setAttribute("ajaxData", ajaxData);
		
		return "/WEB-INF/views/common/ajax_view.jsp";
	}

}

Ajax view - JSP

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
${ajaxData}

Member.properties

/member/checkDuplicatedId.do=kr.member.action.CheckDuplicatedIdAction

Register User Form - JS 부분

$(function(){
	let idChecked = 0; // 0: 중복, id 중복 체크 미실시, 1: 미중복
	// 아이디 중복 체크
	$('#id_check').click(function(){
		if(!/^[A-Za-z0-9]{4,12}$/.test($('#id').val())){
			alert('영문 또는 숫자 사용, 최소 4자 ~ 최대 12자 사용');
			$('#id').val('').focus();
			return;
		}
		
		// 서버와 통신
		$.ajax({
			url:'checkDuplicatedId.do',
			type:'post',
			data:{id:$('#id').val()},
			dataType: 'json',
			success: function(param){
				if(param.result=='idNotFound'){
					idChecked = 1;
					$('#message_id').css('color','black').text('등록 가능 ID');
				}else if(param.result=='idDuplicated'){
					idChecked = 0;
					$('#message_id').css('color','red').text('중복된 ID');
					$('#id').val('').focus();
				} else{
					idChecked=0;
					alert('ID 중복 체크 오류 발생');
				}
			},
			error:function(){
				idChecked = 0;
				alert('Network Error Occurred');
			}
		})
		
	});// end of Click
	
	// 아이디 중복 안내 메시지 초기화 및 아이디 중복 값 초기화
	$('#register_form #id').keydown(function(){
		idChecked = 0;
		$('#message_id').text('');
		
	});// end of Keydown
	
	// 회원 정보 등록 유효성 체크
	$('#register_form').submit(function(){
		const items = document.querySelectorAll('.input-check');
		for(let i=0; i<items.length; i++){
			if(items[i].value.trim()==''){
				const label = document.querySelector('label[for="'+items[i].id+'"]');
				alert(label.textContent+' 필수 입력');
				 items[i].value = '';
		            items[i].focus();
		            return false;
		        } // if 4
			
		        if(items[i].id == 'id' && !/^[A-Za-z0-9]{4,12}$/.test($('#id').val())){
		            alert('영문 또는 숫자 사용, 최소 4자 ~ 최대 12자 사용');
		            $('#id').val('').focus();
		            return false;
		       } // if 3
		       
		        if(items[i].id == 'id' && idChecked == 0){
		            alert('ID 중복 체크는 필수입니다.');
		            return false;
		        } // if 2
		        
		        if(items[i].id == 'zipcode' && !/^[0-9]{5}$/.test($('#zipcode').val())){
		        	alert('우편 번호를 입력하세요(숫자 5자리)');
		        	$('#zipcode').val('').focus();
		            return false;
		        } // if 1
		}
	}); // end of submit
});

Login Form Action

package kr.member.action;

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

import kr.controller.Action;

public class LoginFormAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		
		return "/WEB-INF/views/member/loginForm.jsp";
	}

}

Login Form - HTML

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap" rel="stylesheet">
<script type="text/javascript" src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
$(function(){
	$('#login_form').submit(function(){
		if($('#id').val().trim()==''){
			alert('아이디를 입력하세요');
			$('#id').val('').focus();
			return false;
		}
		if($('#passwd').val().trim()==''){
			alert('비밀번호를 입력하세요');
			$('#passwd').val('').focus();
			return false;
		}
	})
});
</script>
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<div class="content-main">
		<h2>Login</h2>
	</div>
	<form action="login.do" id="login_form" method="post">
		<ul>
			<li class="floating-label">
				<input type="text" class="form-input" placeholder="ID" name="id" id="id" maxlength="12" autocomplete="off">
				<label for="id">ID</label>
			</li>
			<li class="floating-label">
				<input type="password" class="form-input" placeholder="PW" name="passwd" id="passwd" maxlength="12">
				<label for="passwd">PW</label>
			</li>
		</ul>
		<div class="align-center">
		<input type="submit" value="Login"> 
		<input type="button" value="Home" onclick="location.href='${pageContext.request.contextPath}/main/main.do'">
		</div>
	</form>
</div>
</body>
</html>

Login Action

package kr.member.action;

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

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;

public class LoginAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		request.setCharacterEncoding("UTF-8");
		
		String id = request.getParameter("id");
		String passwd= request.getParameter("passwd");
		
		MemberDAO dao = MemberDAO.getInstance();
		MemberVO member= dao.checkMember(id);
		
		boolean check = false;
		
		if (member != null) {
			// 동일한 id 존재
			// 비밀번호 일치 여부 체크
			check = member.isCheckedPassword(passwd);
			// 정지 회원의 경우 상태 표시
			request.setAttribute("auth", member.getAuth());
		}
		
		if(check) {
			// 인증 성공, 로그인 처리
			HttpSession session = request.getSession();
			session.setAttribute("user_num", member.getMem_num());
			session.setAttribute("user_id", member.getId());
			session.setAttribute("user_auth", member.getAuth());
			session.setAttribute("user_photo", member.getPhoto());
		
			// 메인으로 리다이렉트
			return "redirect:/main/main.do";
		}
		// 인증 실패
		return "/WEB-INF/views/member/login.jsp";
	}

}

Login JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:choose>
	<c:when test="${auth == 1}">
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 정보</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap" rel="stylesheet">
</head>
<body>
	<div class="page-main">
		<jsp:include page="/WEB-INF/views/common/header.jsp"/>
		<div class="content-main">
			<h2>회원 정보</h2>
			<div class="result-display">
				<div class="align-center">
				정지된 회원 ID입니다.<br><br>
				<input type="button" value="홈으로" onclick="location.href='${pageContext.request.contextPath}/main/main.do'">
				</div>
			</div>
		</div>
	</div>
</body>
</html>
	</c:when>
	<%-- auth가 1이 아닌 경우 --%>
	<c:otherwise>
	<script type="text/javascript">
		alert('ID 또는 PW가 불일치합니다.');
		history.go(-1);
	</script>
	</c:otherwise>
</c:choose>

Logout Action

package kr.member.action;

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

import kr.controller.Action;

public class LogoutAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		HttpSession session = request.getSession();
		
		session.invalidate();
		
		// 메인으로 redirect
		return "redirect:/main/main.do";
	}

}



Get Member - DAO

public MemberVO getMember(int mem_num) throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = null;
		MemberVO member = null;
		try {
			conn = DBUtil.getConnection();
			sql = "SELECT * FROM zmember_detail JOIN zmember USING(mem_num) WHERE mem_num=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, mem_num);
			rs = pstmt.executeQuery();
			if(rs.next()) {
				member = new MemberVO();
				member.setId(rs.getString("id"));
				member.setName(rs.getString("name"));
				member.setPhone(rs.getString("phone"));
				member.setEmail(rs.getString("email"));
				member.setZipcode(rs.getString("zipcode"));
				member.setAddress1(rs.getString("address1"));
				member.setAddress2(rs.getString("address2"));
				member.setPhoto(rs.getString("photo"));
				member.setReg_date(rs.getDate("reg_date"));
				member.setModify_date(rs.getDate("modify_date"));
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			DBUtil.executeClose(rs, pstmt, conn);
		}
		return member;
	}

My Page Action

package kr.member.action;

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

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;

public class MyPageAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		request.setCharacterEncoding("utf-8");
		
		HttpSession session = request.getSession();
		Integer user_num = (Integer)session.getAttribute("user_num");
		
		if(user_num == null) { // 로그인 되지 않은 경우
			return "redirect:/member/loginForm.do";
		}
		
		// 로그인 완료 후
		MemberDAO dao = MemberDAO.getInstance();
		MemberVO member = dao.getMember(user_num);
		
		request.setAttribute("member", member);
		
		return "/WEB-INF/views/member/myPage.jsp";
	}

}

My Page - JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Page</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap" rel="stylesheet">
<script type="text/javascript" src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<div class="content-main">
	<h2>My Page</h2>
	<div class="mypage-div">
		<h3>Profile Photo</h3>
		<ul>
			<li>
				<c:if test="${empty member.photo}">
					<img alt="profile photo" src="${pageContext.request.contextPath}/images/face.png"
						width="200" height="200" class="my-photo">
				</c:if>
				<c:if test="${!empty member.photo}">
					<img alt="profile photo" src="${pageContext.request.contextPath}/upload/${member.photo}"
						width="200" height="200" class="my-photo">
				</c:if>
			</li>
			<li>
				<div class="align-center">
					<input type="button" value="수정" id="photo_btn">
				</div>
				<div id="photo_choice" style="display: none;">
					<input type="file" id="photo" accept="image/gif,image/png,image/jpeg">
					<input type="button" value="전송" id="photo_submit">
					<input type="button" value="취소" id="photo_reset">
				</div>
			</li>
		</ul>
		<h3>연락처 <input type="button" id="tel_btn" value="연락처 수정" onclick="location.href='modifyUserForm.do'"> </h3>
		
		<ul>
			<li>ID : ${member.id }</li>
			<li>이름 : ${member.name }</li>
			<li>전화번호 : ${member.phone }</li>
			<li>E-mail : ${member.email }</li>
			<li>우편번호 : ${member.zipcode }</li>
			<li>주소 : ${member.address1} ${member.address2}</li>
			<li>가입일 : ${member.reg_date }</li>
			<c:if test="${!empty member.modify_date }">
				<li>최근 정보 수정일 : ${member.modify_date }</li>
			</c:if>		
		</ul>
		<h3>비밀번호 수정</h3>
		<h3>회원 탈퇴</h3>
	</div>
	
	<div class="mypage-div">
		<h3>관심 게시물 목록</h3>
	</div>
	
	<div class="mypage-end">
	</div>
 </div>
</div>
</body>
</html>

Update Photo - DAO

	public void updateMyPhoto(String photo, int mem_num) throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		try {
			conn= DBUtil.getConnection();
			sql="UPDATE zmember_detail SET photo=? WHERE mem_num=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, photo);
			pstmt.setInt(2, mem_num);
			pstmt.executeUpdate();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			DBUtil.executeClose(null, pstmt, conn);
		}
	}

Update My Photo Action

package kr.member.action;

import java.util.HashMap;
import java.util.Map;

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

import org.codehaus.jackson.map.ObjectMapper;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.util.FileUtil;

public class UpdateMyPhotoAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		Map<String, String> mapAjax = new HashMap<String, String>();
		
		HttpSession session = request.getSession();
		Integer user_num = (Integer)session.getAttribute("user_num");
		
		if(user_num==null) { // 로그인 되지 않은 경우
			mapAjax.put("result", "Logout");
			return "redirect:/member/loginForm.do";
		} else { // 로그인 된 경우
			// 전송된 데이터 인코딩 타입 지정
			request.setCharacterEncoding("UTF-8");
			// 파일 업로드 처리
			String photo = FileUtil.createFile(request, "photo");
			
			MemberDAO dao = MemberDAO.getInstance();
			// 프로필 사진 수정
			dao.updateMyPhoto(photo, user_num);
			
			// 이전 파일 삭제 처리
			String user_photo = (String) session.getAttribute("user_photo");
			FileUtil.removeFile(request, user_photo);
			
			session.setAttribute("user_photo", photo);
			mapAjax.put("result", "success");
		}
		
		ObjectMapper mapper = new ObjectMapper();
		String ajaxData = mapper.writeValueAsString(mapAjax);
		
		request.setAttribute("ajaxData", ajaxData);
		
		return "/WEB-INF/views/common/ajax_view.jsp";
	}

}

My Page - JSP

Script 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Page</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap" rel="stylesheet">
<script type="text/javascript" src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
$(function(){
	$('#photo_btn').click(function(){
		$('#photo_choice').show();
		$(this).hide();
	}); // end of Click
	
	// 이미지 미리보기
	let photo_path = $('.my-photo').attr('src'); // 처음 화면에 보여지는 이미지 읽기
	$('#photo').change(function(){
		let my_photo = this.files[0];
		if(!my_photo){
			// 선택을 취소하면 원래 처음 화면으로 되돌림
			$('.my-photo').attr('src',photo_path);
			return;
		}
		if(my_photo.size > 1024*1024){
			alert(Math.round(my_photo.size/1024) + 'kbytes(1024kbytes까지만 업로드 가능)');
			$('.my-photo').attr('src',photo_path);
			$(this).val(''); // 선택한 파일 정보 지우기
			return;
		}
		// 화면에 이미지 미리보기
		const reader = new FileReader();
		reader.readAsDataURL(my_photo);
		
		reader.onload=function(){
			$('.my-photo').attr('src',reader.result);			
		};
	}); // end of Change
	
	// 이미지 미리보기 취소
	$('#photo_reset').click(function(){
		// 초기 이미지 표시
		$('.my-photo').attr('src',photo_path); // 이미지 미리보기 전 이미지로 되돌리기
		$('#photo').val('');
		$('#photo_choice').hide();
		$('#photo_btn').show(); // 수정 버튼 표시
		
	})
});
</script>
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<div class="content-main">
	<h2>My Page</h2>
	<div class="mypage-div">
		<h3>Profile Photo</h3>
		<ul>
			<li>
				<c:if test="${empty member.photo}">
					<img alt="profile photo" src="${pageContext.request.contextPath}/images/face.png"
						width="200" height="200" class="my-photo">
				</c:if>
				<c:if test="${!empty member.photo}">
					<img alt="profile photo" src="${pageContext.request.contextPath}/upload/${member.photo}"
						width="200" height="200" class="my-photo">
				</c:if>
			</li>
			<li>
				<div class="align-center">
					<input type="button" value="수정" id="photo_btn">
				</div>
				<div id="photo_choice" style="display: none;">
					<input type="file" id="photo" accept="image/gif,image/png,image/jpeg">
					<input type="button" value="전송" id="photo_submit">
					<input type="button" value="취소" id="photo_reset">
				</div>
			</li>
		</ul>
		<h3>연락처 <input type="button" id="tel_btn" value="연락처 수정" onclick="location.href='modifyUserForm.do'"> </h3>
		
		<ul>
			<li>ID : ${member.id }</li>
			<li>이름 : ${member.name }</li>
			<li>전화번호 : ${member.phone }</li>
			<li>E-mail : ${member.email }</li>
			<li>우편번호 : ${member.zipcode }</li>
			<li>주소 : ${member.address1} ${member.address2}</li>
			<li>가입일 : ${member.reg_date }</li>
			<c:if test="${!empty member.modify_date }">
				<li>최근 정보 수정일 : ${member.modify_date }</li>
			</c:if>		
		</ul>
		<h3>비밀번호 수정</h3>
		<h3>회원 탈퇴</h3>
	</div>
	
	<div class="mypage-div">
		<h3>관심 게시물 목록</h3>
	</div>
	
	<div class="mypage-end">
	</div>
 </div>
</div>
</body>
</html>

MY PAGE 화면

profile photo의 수정 버튼 클릭시, 사진 수정 가능한 input[type="file"] 보여짐

팀 프로젝트

다양한 의견들 제시하면서 어떤 프로젝트를 진행하면 좋을지 의논하다가 내가 낸 아이디어인
개발자들을 위한 팀 프로젝트 팀원 구하는 웹사이트를 만들기로 결정함

그래서 참고할만한 사이트들이 있을지 찾아보았음!

  1. https://holaworld.io/
    => 프로젝트 인원 구하기, 스터디 구하기, 내가 생각한 사이트와 가장 유사함

  2. https://bside.best/careercard
    => 조금 더 커리어 쪽에 집중되어 있는 느낌

  3. https://www.beginmate.com/
    => IT 분야 외에도 많은 분야의 프로젝트도 진행함

  4. https://letspl.me/people
    => 분야가 다양하고, 본인의 소개 개인과 채팅으로 소통 가능함

요구사항 정의서를 작성 시작함!

profile
Lucky Things🍀

0개의 댓글