31일차(2)/jsp(12) : 회원가입, 로그인 기능 구현하기
Step04_Final 프로젝트 생성
- 회원가입, 로그인, 로그아웃 기능을 만들 예정!
- 회원정보 테이블을 오라클에서 만들 수도 있지만,
이클립스에 추가기능을설치해서 이클립스에서 DB를 제어하도록 할 수 있다.
- java EE환경에서 new jsp파일 생성!
<index.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//session scope에 id라는 키값으로 저장된 값이 있는지 읽어와 본다.(없으면 null)
String id=(String)session.getAttribute("id");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/index.jsp</title>
</head>
<body>
<div class="container">
<%if(id != null) {%>
<p>
<strong><%=id %></strong>님 로그인중....
<a href="${pageContext.request.contextPath }/users/logout.jsp">로그아웃</a>
</p>
<%}else{ %>
<a href="${pageContext.request.contextPath }/users/loginform.jsp">로그인</a>
<%} %>
<h1>인덱스 페이지입니다.</h1>
<ul>
<li><a href="${pageContext.request.contextPath }/users/signup_form.jsp">회원가입</a></li>
</ul>
</div>
</body>
</html>
- /users/ <signup_form.jsp> 생성!
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/signup_form.jsp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1>회원 가입 폼입니다.</h1>
<form action="signup.jsp" method="post">
<div>
<label for="id" class="control-label">아이디</label>
<input type="text" class="form-control" name="id" id="id" />
</div>
<div>
<label for="pwd" class="control-label">비밀번호</label>
<input type="text" class="form-control" name="pwd" id="pwd" />
</div>
<div>
<label for="email" class="control-label">이메일</label>
<input type="text" class="form-control" name="email" id="email" />
</div>
<button class="btn btn-outline-primary" type="submit">가입</button>
</form>
</div>
</body>
</html>
*DB 연결하기 위한 세팅 필요
- Step02에서 test.util 패키지째로 DbcpBean 복사하기
- Step04 프로젝트에도 web.xml 을 만들어주고,
Step02 프로젝트 web.xml 에서 --DB 접속 설정-- 복사해오기
- lib 안에도 ojdbc6.jar파일을 넣어준다.
- DTO, DAO 만들기
test.users.dto / test.users.dao 패키지 생성-클래스 생성
<UsersDto>
package test.users.dto;
public class UsersDto {
private String id;
private String pwd;
private String email;
private String profile;
private String regdate;
public UsersDto() {}
public UsersDto(String id, String pwd, String email, String profile, String regdate) {
super();
this.id = id;
this.pwd = pwd;
this.email = email;
this.profile = profile;
this.regdate = regdate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getRegdate() {
return regdate;
}
public void setRegdate(String regdate) {
this.regdate = regdate;
}
}
<UsersDao>
package test.users.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import test.users.dto.UsersDto;
import test.util.DbcpBean;
public class UsersDao {
private static UsersDao dao;
//외부에서 객체 생성할 수 없도록
private UsersDao() {}
//참조값을 리턴해주는 static 메소드
public static UsersDao getInstance() {
if(dao==null) {
dao=new UsersDao();
}
return dao;
}
//인자로 전달되는 dto에 있는 아이디와 비밀번호를 이용해서 해당 정보가 유효한 정보인지 여부를 리턴하는 메소드
public boolean isValid(UsersDto dto) {
//아이디 비밀번호 유효성 여부를 담을 변수를 만들고 초기값 false 부여하기
boolean isValid=false;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs=null;
try {
//Connection Pool에서 Connection 객체를 하나 얻어온다.
conn = new DbcpBean().getConn();
//실행할 sql문의 뼈대 구성하기
String sql = "SELECT * FROM users"
+ " WHERE id=? AND pwd=?";
//sql문의 ?에 바인딩할게 있으면 한다.
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getId());
pstmt.setString(2, dto.getPwd());
//SELECT문을 수행하고 결과값을 받아온다.
rs=pstmt.executeQuery();
//SELECT된 ROW가 있는지 확인해본다.
if (rs.next()) {
//select된 row가 있다면 유효한 정보가 맞다.
isValid=true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close(); //Connection Pool에 Connection 반납하기
} catch (Exception e2) {
}
}
return isValid;
}
//회원 한명의 정보를 DB에 저장하고 성공여부를 리턴하는 메소드
public boolean insert(UsersDto dto) {//UsersDto에 id, pwd, email이 있다.
Connection conn = null;
PreparedStatement pstmt = null;
int rowCount = 0;
try {
conn = new DbcpBean().getConn();
String sql = "INSERT INTO users"
+ " (id, pwd, email, regdate)"
+ " VALUES(?, ?, ?, sysdate)";
pstmt = conn.prepareStatement(sql);
//?에 바인딩
pstmt.setString(1, dto.getId());
pstmt.setString(2, dto.getPwd());
pstmt.setString(3, dto.getEmail());
//INSERT or UPDATE or DELETE문을 수행하고 수정,삭제,추가된 row의 개수 리턴
rowCount = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
if (rowCount > 0) {
return true;
} else {
return false;
}
}
}
<signup_form.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/signup_form.jsp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1>회원 가입 폼입니다.</h1>
<form action="signup.jsp" method="post">
<div>
<label for="id" class="control-label">아이디</label>
<input type="text" class="form-control" name="id" id="id" />
</div>
<div>
<label for="pwd" class="control-label">비밀번호</label>
<input type="text" class="form-control" name="pwd" id="pwd" />
</div>
<div>
<label for="email" class="control-label">이메일</label>
<input type="text" class="form-control" name="email" id="email" />
</div>
<button class="btn btn-outline-primary" type="submit">가입</button>
</form>
</div>
</body>
</html>
- 폼으로 id pwd email 값을 받아서 저장!
- 연결되는 signup.jsp생성 필요
<signup.jsp>
<%@page import="test.users.dto.UsersDto"%>
<%@page import="test.users.dao.UsersDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//1. 폼 전송되는 아이디, 비밀번호, 이메일 주소를 읽어온다.
request.setCharacterEncoding("utf-8");
String id=request.getParameter("id");
String pwd=request.getParameter("pwd");
String email=request.getParameter("email");
//2. UsersDto에 담는다.
UsersDto dto= new UsersDto();
dto.setId(id);
dto.setPwd(pwd);
dto.setEmail(email);
//3. UsersDao를 이용해서 DB에 저장하고
boolean isSuccess=UsersDao.getInstance().insert(dto);
//4. 결과를 응답한다.
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/signup.jsp</title>
</head>
<body>
<div class="container">
<%if(isSuccess){ %>
<p>
<strong><%=id %></strong> 님 가입되었습니다.
<a href="loginform.jsp">로그인 하러 가기</a>
</p>
<%} else{%>
<p>
가입에 실패했습니다.
<a href="signup_form.jsp">다시 가입하러 가기</a>
</p>
<%} %>
</div>
</body>
</html>
- 서버가 입력받은 내용을 원활하게 읽어오기 위해서는
signup_from의 label name 속성의 value와
signup의 .getParameter()에 들어가는 값이 반드시 일치해야 한다.
- 회원가입 된다. Quantum DB에 들어가서도 확인할 수 있다.
<loginform.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/loginform.jsp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1>로그인 폼</h1>
<form action="login.jsp" method="post">
<div>
<label for="id" class="form-label">아이디</label>
<input type="text" name="id" id="id" class="form-control" />
</div>
<div>
<label for="pwd" class="form-label">비밀번호</label>
<input type="password" name="pwd" id="pwd" class="form-control" />
</div>
<button class="btn btn-primary" type="submit">로그인</button>
</form>
</div>
</body>
</html>
- UserDao에 id와 pwd가 일치하는 row를 찾는 메소드를 만들어야 한다.
- 폼에 입력되는 값과 비교하여 select 되는 row가 있는지 찾는다.
- and 조건으로 묶으면 id, pwd 둘다 맞아야만 row를 찾을 수 있다. 둘중 하나라도 다르면 로그인 불가!
- 찾은 값이 있으면(유효한 정보이면) session scope에 저장한다.
- '해당 정보가 유효한 정보인지' == 'DB에 해당 정보가 존재하는지' 를 의미한다.
<UsersDao>에 select문 추가
//인자로 전달되는 dto에 있는 아이디와 비밀번호를 이용해서 해당 정보가 유효한 정보인지 여부를 리턴하는 메소드
public boolean isValid(UsersDto dto) {
//아이디 비밀번호 유효성 여부를 담을 변수를 만들고 초기값 false 부여하기
boolean isValid=false;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs=null;
try {
//Connection Pool에서 Connection 객체를 하나 얻어온다.
conn = new DbcpBean().getConn();
//실행할 sql문의 뼈대 구성하기
String sql = "SELECT * FROM users"
+ " WHERE id=? AND pwd=?";
//sql문의 ?에 바인딩할게 있으면 한다.
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getId());
pstmt.setString(2, dto.getPwd());
//SELECT문을 수행하고 결과값을 받아온다.
rs=pstmt.executeQuery();
//SELECT된 ROW가 있는지 확인해본다.
if (rs.next()) {
//select된 row가 있다면 유효한 정보가 맞다.
isValid=true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close(); //Connection Pool에 Connection 반납하기
} catch (Exception e2) {
}
}
return isValid;
}
SELECT * FROM users
WHERE id='banana' AND pwd='1234'
- DB에서 찾아서 T/F값을 반환한다. oracle에서 위와 같이 sql문을 작성한 것과 같다.
저 값이 있으면 true를 반환하고, 없으면 false를 반환하는 것!
- select될 row가 많아야 1개이기 때문에 while문 대신 if문을 쓴다.
(반복문을 돌면서 rs에 목록을 담지 않아도 된다)
- if문 안에 isValid=true 로 바뀌는 값을 넣을 것이므로 위에서 isValid 변수를 미리 만들어준다.
- 먼저 초기값 false를 부여하고, 특정 조건일 경우 true로 바뀌도록 설정한다.
<login.jsp> 로그인할 페이지 추가
<%@page import="test.users.dto.UsersDto"%>
<%@page import="test.users.dao.UsersDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//1. 폼 전송하는 아이디, 비밀번호 읽어오기
request.setCharacterEncoding("utf-8");
String id=request.getParameter("id");
String pwd=request.getParameter("pwd");
UsersDto dto=new UsersDto();
dto.setId(id);
dto.setPwd(pwd);
//2. DB에 실제로 존재하는 맞는 정보인지 확인한다.(맞는 정보이면 로그인 처리도 한다.)
boolean isValid=UsersDao.getInstance().isValid(dto);
if(isValid){
//session scope에 id라는 키값으로 로그인된 아이디 담기
session.setAttribute("id", id);
}
//3. 응답
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/login.jsp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<% if(isValid){ %>
<p class="alert alert-success">
<strong><%=id %></strong> 회원님 로그인되었습니다.
<a href="../index.jsp">인덱스로 이동하기</a>
</p>
<%}else{ %>
<p class="alert alert-danger">
로그인에 실패했습니다.
<a href="loginform.jsp">다시 로그인하기</a>
</p>
<%} %>
</div>
</body>
</html>
- if문 안에 session을 추가해서 정보가 맞을 경우 로그인 처리되도록 한다.
- .setMaxInactiveInterval() : 기본값은 30분이다!
- bootstrap을 추가해주었다.
<div class="container">
<%if(id != null) {%>
<p>
<strong><%=id %></strong>님 로그인중....
<a href="${pageContext.request.contextPath }/users/logout.jsp">로그아웃</a>
</p>
<%}else{ %>
<a href="${pageContext.request.contextPath }/users/loginform.jsp">로그인</a>
<%} %>
</div>
- index 에 로그인 id를 읽어와 로그인 여부에 따라 페이지가 다르게 보이도록 한다.
<logout.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/logout.jsp</title>
</head>
<body>
<%
session.removeAttribute("id");
%>
<script>
alert("정상적으로 로그아웃 되었습니다.");
location.href="${pageContext.request.contextPath }/index.jsp";
</script>
</body>
</html>
- session.removeAttribute("id"); 로 작성하면 세션에 저장된 해당 id가 로그아웃 되는 것.
session.invalidate(); 로 작성해서 세션을 초기화해도 된다!
- 로그아웃하면 알림창이 뜨고, 확인을 누르면 인덱스로 이동하도록 설정
'국비교육(22-23)' 카테고리의 다른 글
32일차(1)/jsp(13) : request / session / filter 복습 (0) | 2022.11.22 |
---|---|
31일차(2)/jsp(12) : 회원전용 페이지 기능 구현하기(Filter) (0) | 2022.11.21 |
[참고] Eclipse에 Quantum DB 설치 (0) | 2022.11.21 |
30일차(2)/jsp(10) : Session Scope (0) | 2022.11.18 |
30일차(1)/jsp(9) : Request Scope (0) | 2022.11.18 |