Project/SemiProject

[211208] Join & 로그인 페이지 review

감자탈출기 2021. 12. 10. 16:38

회원가입(Join) 페이지

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="com.web.account.model.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Font+Name">
<!-- join.css 파일  -->
<link type="text/css" rel="stylesheet" href="/static/css/join.css">
<!-- 유효성검사 Javascript -->
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="/static/js/join.js?ver=1"></script>
<!-- Daum 주소 API -->
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script type="text/javascript">
window.onload = function(){
	// 주소 창을 클릭하면 다음 주소API 창을 띄운다.
    document.querySelector("input[name=u_address]").addEventListener("click", function(){
        new daum.Postcode({
            oncomplete: function(data) {
            	// 검색한 도로명 주소를 칸에 입력한다.
                document.querySelector("input[name=u_address]").value = data.address;
            	// 검색한 도로명의 주소 중 "동"을 이동가능 시간(분) 앞 칸에 입력한다.
                document.querySelector("input[name=dong]").value = data.bname;
            }
        }).open();
    });
}
</script>
	<title>회원가입</title>
</head>
<body>

	<% // 오류가 발생하여 작성 페이지로 돌아왔을 때 기존에 입력한 값을 가져오기
		AccountDTO initData = new AccountDTO();
		String error = "";
		if(request.getAttribute("init") != null) {
			initData = (AccountDTO) request.getAttribute("init");
		}
	%>
	
	<!-- 숨고 페이지 헤더 -->
	<div id="header">
	<span class="material-icons" id="home">home</span>
		<span class="logo">
			<a href="/" class="logo">숨고</a>
		</span>
		<span class="material-icons">face</span>
		<span>
			<a href="/join">회원가입 페이지</a>
		</span>
	</div>
	
	<!-- 회원가입 입력 폼 -->
	<form class="join_form" action="./join" method="post" name="frm">
		<!-- 고수, 일반 선택 -->
		<div class="group">
			<div class="box1">
				<ul>
					<li>
						<input type="radio" name="division" value="고수">
						<span class="radio_text"> 고 수</span>
					</li>
					<li>
						<input type="radio" name="division" value="일반">
						<span class="radio_text"> 일 반</span>
					</li>
				</ul>
				<!-- error box[0] division -->
				<div class="error_box" id="errdivi" style="text-align: center; display: none;">
					고수와 일반 중 하나를 선택바랍니다.
				</div>
			</div>
		</div>
		
		<!-- 아이디, 비밀번호, 비밀번호 재확인 -->
		<div class="group">
			<div class="tool_box">
				<label>아이디</label>
				<div class="box">
					<input type="text" class="inbox1" name="u_id" 
						id="id"  value="<%=initData.getU_id() %>" 
						maxlength="20">
				</div>
				<!-- error box[1] id -->
				<div class="error_box" id="errid" style="text-align: center; display: none;">
					아이디를 입력바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>비밀번호</label>
				<div class="box">
					<input type="password" class="inbox1 check" name="u_pwd" 
					id="pw" maxlength="20" autocomplete="off">
				</div>
				<!-- error box[2] pw -->
				<div class="error_box" style="display: none;">
					비밀번호를 입력바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>비밀번호 확인</label>
				<div class="box">
					<input type="password" class="inbox1 check" name="pwd_check" 
					id="pwCheck" maxlength="20" autocomplete="off">
				</div>
				<!-- error box[3] pwcheck -->
				<div class="error_box" style="display: none;">
					비밀번호가 일치하지 않습니다.
				</div>
			</div>
		</div>
		
		<!-- 이름, 성별, 생년월일, 연락처, 이메일 -->
		<div class="group">
			<div class="tool_box">
				<label>이름</label>
				<div class="box">
					<input type="text" class="inbox1 check" name="u_name" 
					id="nameis">
				</div>
				<!-- error box[4] name-->
				<div class="error_box" style="display: none;">
					이름을 입력바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>성별</label>
				<div class="box1">
					<ul>
						<li>
				  			<input type="radio" name="u_gender" value="남">
				  			<span class="radio_text"> 남 자</span>
				 		</li>
				 		<li>
						 	<input type="radio" name="u_gender" value="여">
						 	<span class="radio_text"> 여 자</span>
						</li>
					</ul>
				</div>
				<!-- error box[5] gender-->
				<div class="error_box" style="text-align: center; display: none;">
					성별을 선택바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>생년월일</label>
				<div class="box">
					<input type="text" class="inbox1 check" name="u_birth"
					id="birthDay" placeholder="숫자만 입력 ex) 19910101"
					value="<%=initData.getU_birth() %>" maxlength="8">
				</div>
				<!-- error box[6] birth-->
				<div class="error_box" id="birth_error" style="display: none;">
					생년월일을 입력바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>휴대폰</label>
				<div class="box">
					<input type="text" class="inbox1 check" name="u_phone" 
					id="phoneNum" value="<%=initData.getU_phone() %>"
					placeholder="번호(숫자)만 입력 ex) 01012345678" maxlength="11">
				</div>
				<!-- error box[7] phone-->
				<div class="error_box" style="display: none;">
					휴대폰 번호를 입력바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>이메일</label>
				<div class="box">
					<input type="email" class="inbox1 check" name="u_email" 
					id="myEmail" value="<%=initData.getU_email() %>"
					placeholder="abcd@Email.com">
				</div>
				<!-- error box[8] email-->
				<div class="error_box" style="display: none;">
					이메일 주소를 입력바랍니다.
				</div>
			</div>
		</div>
		
		<!-- 주소, 이동가능 시간(분) -->
		<div class="group">
			<div class="tool_box">
				<label>주소</label>
				<div class="box">
					<input type="text" name="u_address" class="inbox1"
					id="address" placeholder="이 곳을 클릭하여 주소를 검색하세요." readonly>
				</div>
				<!-- error box[9] address-->
				<div class="error_box" style="display: none;">
					입력 창을 클릭하여 주소를 검색바랍니다.
				</div>
			</div>
			<div class="tool_box">
				<label>이동가능 시간(분)</label>
				<div class="box">
					<input type="text" name="dong" class="inbox2" readonly> 에서 부터
					<input type="number" name="u_possible_time" 
					id="possibletime" class="inbox2"> 분
				</div>
				<!-- error box[10] possibletime-->
				<div class="error_box" style="display: none;">
					이동가능한 시간을 숫자로 입력바랍니다.
				</div>
			</div>
		</div>
		
		<div class="group">		
		<a href="/" style="color: gray;"><button type="button" id="bt2">이전으로</button></a>
		<button type="submit" id="bt1">가입하기</button>
		</div>
	</form>
</body>
</html>

 

 

LoginController

package com.web.account.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
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 com.web.account.model.AccountDTO;
import com.web.account.model.AccountService;

@WebServlet("/join")
public class joinController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet
	(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		String view = "/WEB-INF/jsp/account/join.jsp";
		RequestDispatcher rd = request.getRequestDispatcher(view);
		rd.forward(request, response);
	}

	protected void doPost
	(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		//Parameter로 전달 되는 데이터 한글인식 가능하게 처리
		request.setCharacterEncoding("UTF-8");
		//browser로 전달 되는 데이터 한글인식 가능하게 처리
		response.setContentType("text/html; charset=UTF-8");
		
		// MEMBER DB 저장하기 위한 입력 값
		String u_id= request.getParameter("u_id");
		String u_pwd = request.getParameter("u_pwd");
		String u_name = request.getParameter("u_name");
		String u_birth = request.getParameter("u_birth");
		String u_gender = request.getParameter("u_gender");
		String u_phone = request.getParameter("u_phone");
		String u_email = request.getParameter("u_email");
		String u_address = request.getParameter("u_address");
		String u_possible_time = request.getParameter("u_possible_time");
		
		// 구분으로 얻은 고수의 값
		String check = request.getParameter("division");
		
		AccountDTO dto = new AccountDTO(u_id, u_pwd, u_name, u_birth,
				u_gender, u_phone, u_email, 
				u_address, u_possible_time, check);

		AccountService service = new AccountService();
		if(service.isValid(dto)) {
			if(service.add(dto)) {
				response.sendRedirect("/"); //회원가입 무사히 마쳤다면 메인페이지로 리다이렉트
			} else {
				request.setAttribute("init", dto); // (속성이름, 속성값)
//				request.setAttribute("error", "ID 중복");

				String view ="/WEB-INF/jsp/account/join.jsp";
				RequestDispatcher rd = request.getRequestDispatcher(view);
				rd.forward(request, response);
			}
		} else {
			request.setAttribute("init",dto);
//			request.setAttribute("error","유효성검사 실패");
			String view ="/WEB-INF/jsp/account/join.jsp";
			RequestDispatcher rd = request.getRequestDispatcher(view);
			rd.forward(request, response);
		}
	}

}

회원가입이 정상적으로 되지 않았을 경우 사용자 입력 값이 삭제되지 않고 작성하던 그대로 남겨주기 위해 joinController doPost 에서 (post : join_form method type) request.setAttribute("init", dto); 로 jsp 페이지로 넘겨준다.

jsp 페이지에는 초기데이터 형식으로 집어넣어 주는 것이다.

(ex. value="<%=initData.getU_email() %>") 

 

 

AccountDTO 에 가입정보 저장되는 형태. (db MEMBER 테이블에 저장) - u_id : 사용자 입력 아이디, u_no : 시퀀스 (기본키이자 로그인 시 세션 값! 될 예정)

 

 


로그인 페이지

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!doctype HTML>
<html>
<head>
	<meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="/static/css/login.css">
<script type="text/javascript" src="/static/js/login.js"></script>
	<title>로그인</title>
</head>
<body>
<form action="/login" method="post">
	<div class="main-container">
		<div class="main-wrap">
		<header>
		<div id="header">
		<% // 숨고 누르면 메인페이지로 이동 %>
		<h3 class="font1">
			<a href="/">숨고</a>
		</h3>
		<h3>로그인 페이지</h3>
	</div>
		<div class="sel-lang-wrap">
				<select class="lang-select">
					<option>한국어</option>
					<option>English</option>
				</select>
			</div>
            <div class="logo-wrap">
                <h1>로그인</h1>
                </div>
		</header>
		<section class="login-input-section-wrap">
			<div class="login-input-wrap">	
				<input placeholder="아이디를 입력하세요." type="text" name="user_id"></input>
			</div>
			<div class="login-input-wrap password-wrap">	
				<input placeholder="비밀번호를 입력하세요" type="password" name="user_pw"></input>
			</div>
			<div class="login-button-wrap">
				<button>로그인</button>
			</div>
			<div class="login-stay-sign-in">
				<i class="far fa-check-circle"></i>
				<span>비밀번호 찾기</span>
			</div>
		</section>
		<section class="Easy-sgin-in-wrap">
            <h2>Easier sign in</h2>
			<ul class="sign-button-list">
				<li><button><i class="fas fa-goolgle"></i><span><img src=>구글 로그인</span></button></li>
				<li><button><i class="fab fa-facebook"></i><span>페이스북 로그인</span></button></li>
				<li><button><i class="fab fa-kakao"></i><span>카카오 로그인</span></button></li>
			</ul>
			<p class="forget-msg"> 아이디가 없으신가요? | Sign up</p>
		</section>
		<footer>
			<div class="copyright-wrap">
			<span>	<img src="img/logo.png">  © KH프로젝트 All Rights Reserved.</span>
			</div>
		</footer>
		</div>
	</div>
	</form>
</body>
</html>

 

 

package com.web.login.controller;
	import java.io.IOException;

	import javax.servlet.RequestDispatcher;
	import javax.servlet.ServletException;
	import javax.servlet.annotation.WebServlet;
	import javax.servlet.http.Cookie;
	import javax.servlet.http.HttpServlet;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;
	import javax.servlet.http.HttpSession;

	import com.web.login.model.*;

	@WebServlet("/login")
	public class loginController extends HttpServlet {
		private static final long serialVersionUID = 1L;
	    
		protected void doGet(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
			
			LoginService service = new LoginService();
			int i = service.test();
			request.setAttribute("i", i);
			
			String view = "/WEB-INF/jsp/login/login.jsp";
			RequestDispatcher rd = request.getRequestDispatcher(view);
			rd.forward(request, response);
		}
		
		protected void doPost(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
			String username = request.getParameter("user_id");
			String password = request.getParameter("user_pw");
			System.out.println(username+":"+password);
			LoginDTO dto = new LoginDTO();
			dto.setUsername(username);
			dto.setPassword(password);
			LoginService service = new LoginService();
			if(service.login(dto)) {
				HttpSession session = request.getSession();
				session.setAttribute("s_user_id", dto.getId()); // 세션객체는 서버가 관리한다.(서버에 저장된다.)
				response.sendRedirect("/");
			} else {
				System.out.println("로그인 실패");
			}
		}

	}

 

웹 클라이언트가 서버에게 요청을 보내면 서버는 클라이언트를 식별하는 session id를 생성한다.

서버는 session id로 key와 value를 저장하는 HttpSession을 생성하고, session id를 저장하고 있는 쿠키를 생성하여 클라이언트에게 전송한다.

클라이언트는 서버 측에 요청을 보낼 때, session id를 가지고 있는 쿠키를 전송한다.

서버는 쿠키의 session id로 HttpSession을 찾는다.

javax.servlet.http.HttpSession으로 세션 데이터를 다룰 수 있다.

 

1) 세션 생성 및 얻기

HttpSession session = request.getSession();

 

request의 getSession() 메서드는 서버에 생성된 세션이 있다면 세션을 반환하고, 없다면 새 세션을 생성하여 반환한다. (인수 default가 true)

 

2) 세션에 값 저장하기

setAttribute(String name, Object value)

setAttribute는 name, value 쌍으로 객체 Object를 저장하는 메서드다.

세션이 유지되는 동안 저장된다.

 

session.setAttribute(이름, 값)

이렇게 사용할 수 있다.

 

https://enai.tistory.com/29

세션 설명 출처

 

로그인하면(login form method = post) 세션 값 : 시퀀스로 생성되는 u_no 가 될 것임 

protected void doPost(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
			String username = request.getParameter("user_id");
			String password = request.getParameter("user_pw");
			System.out.println(username+":"+password);
			LoginDTO dto = new LoginDTO();
			dto.setUsername(username);
			dto.setPassword(password);
			LoginService service = new LoginService();
			if(service.login(dto)) {
				HttpSession session = request.getSession();
				session.setAttribute("s_user_id", dto.getId());     
                // dto.getId() : u_no (ACCOUNTS 테이블에 저장 되어 있음)
                
				response.sendRedirect("/");
			} else {
				System.out.println("로그인 실패");
			}
		}

사용자 입력 값인 유저네임(사용자id)과 패스워드를 dto 객체에 저장 후 service.login(dto) 로 넘겨 db에 저장된 MEMBER 테이블의 정보를 select, LoginDTO 객체에 담은 뒤 반환, dto.getId()로 기본 키 시퀀스 값인 유저넘버를 세션 값으로 저장한다.

 

LoginService

package com.web.login.model;

import java.util.List;

public class LoginService {

	public boolean isValid(LoginDTO dto) {
		if(isEmpty(dto.getUsername()) || isEmpty(dto.getPassword())
				|| isEmpty(dto.getEmail())) {
			return false;
		}
		return true;
	}

	private boolean isEmpty(String str) {
		return str.isEmpty();
	}

	public boolean add(LoginDTO dto) {
		LoginDAO dao = new LoginDAO();
		int count = dao.select(dto.getUsername()).size();
		if(count == 0) {
			boolean res = dao.insert(dto);
			if(res) {
				dao.commit();
				dao.close();
				return true;
			} else {
				dao.rollback();
				dao.close();
				return false;
			}
		} else {
			return false;
		}
	}
	public int test() {
	      LoginDAO dao = new LoginDAO();
	      int i = dao.test();
	      dao.close();
	      return i;
	}
	
	public boolean login(LoginDTO dto) {
		LoginDAO dao = new LoginDAO();
		List<LoginDTO> data = dao.select(dto.getUsername());
		System.out.println("Service:"+data.size());
		if(data.size() == 1) { //가입한 회원이라면 해당하는 select 값이 한줄 - dto 리스트 안에서 첫번째이자 유일한 객체
			LoginDTO userData = data.get(0); // 첫번째 dto 객체 저장
			if(dto.equalsPassword(userData)) {
				dto.setId(userData.getId());
				dao.close();
				return true;
			} else {
				dao.close();
				return false;
			}
		} else {
			dao.close();
			return false;
		}
	}

}

 

LoginDAO

package com.web.login.model;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import com.db.conn.OracleConnect;

public class LoginDAO {
	private OracleConnect oc;
	
	public LoginDAO() {
		this.oc = new OracleConnect(true);
	}

	public boolean insert(LoginDTO dto) {
		String query = "INSERT INTO ACCOUNTS VALUES("
				+ "ACCOUNTS_SEQ.NEXTVAL, "
				+ "'" + dto.getUsername() + "', "
				+ "'" + dto.getPassword() + "', "
				+ "'" + dto.getEmail() + "', "
				+ "SYSDATE)";
		
		int res = oc.insert(query);
		
		return res == 1 ? true : false;
	}

	public List<LoginDTO> select(String username) {
		String query = "SELECT * FROM MEMBER WHERE U_ID = '" + username + "'";
		ResultSet res = oc.select(query);
		
		List<LoginDTO> datas = new ArrayList<LoginDTO>();
		try {
			while(res.next()) {
				LoginDTO dto = new LoginDTO();
				dto.setUsername(res.getString("U_ID"));
				dto.setPassword(res.getString("U_PWD"));
				dto.setId(res.getInt("U_NO"));
				datas.add(dto);
			}
			res.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return datas;
	}
	public int test() {
	      String query="SELECT * FROM MEMBER";
	      ResultSet res = oc.select(query);
	      int a = 0;
	      try {
	         while(res.next()) {
	            a++;
	         }
	         res.close();
	      } catch(SQLException e) {
	         e.printStackTrace();
	      }
	      return a;     
	}
	public void commit() {
		oc.commit();
	}
	
	public void rollback() {
		oc.rollback();
	}
	
	public void close() {
		oc.close();
	}

}

 

LoginDTO

package com.web.login.model;

import java.sql.Date;

public class LoginDTO {
	private int id;				// Column Name : ID
	private String username;	// Column Name : USERNAME
	private String password;	// Column Name : PASSWORD
	private String email;		// Column Name : EMAIL
	private Date joinDate;		// Column Name : JOINDATE
	
	public LoginDTO() {
		this.username = "";
		this.email = "";
	}
	
	public LoginDTO(String username, String password) {
		this.username = username;
		this.password = password;
	}
	
	public LoginDTO(String username, String password, String email) {
		this(username, password);
		this.email = email;
	}
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public String getUsername() {
		return username;
	}
	
	public void setUsername(String username) {
		this.username = username;
	}
	
	public String getPassword() {
		return password;
	}
	
	public void setPassword(String password) {
		this.password = password;
	}
	
	public String getEmail() {
		return email;
	}
	
	public void setEmail(String email) {
		this.email = email;
	}
	
	public Date getJoinDate() {
		return joinDate;
	}
	
	public void setJoinDate(Date joinDate) {
		this.joinDate = joinDate;
	}
	
	public boolean equalsPassword(LoginDTO dto) {
		return this.password.equals(dto.getPassword());
	}
}