today_is
[ jsp ] 회원기능 구현 (1) - 회원가입, 로그인, 로그아웃 본문
오늘의 목표
회원테이블을 만들어서
사용자가 사용할 수 있는 회원기능들을 구현해보자!
member 테이블
varchar2(300) userid;
varchar2(300) userpw;
varchar2(300) username;
varchar2(100) gender;
varchar2(500) email;
DTO, DAO 생성
DTO
: 필드와 getter & setter 생성
DAO
: DB와 연결할 수 있도록 DAO 에 connection 객체를 생성해야함
Connection을 미리 생성하여 관리하는 DataSource 객체는 context.xml에 정의되어 있다
미리 준비한 DataSource를 자바 객체로 불러오기 위해서는 Context를 객체화해서 불러와야 한다
Connection 이후에는 이전 순서대로 PreparedStatement, ResultSet]등이 필요하다
1) context.xml 의 내용을 자바 객체로 불러온다. new InitialContext();
2) context.xml 에 작성한 DataSource 객체를 지정한 이름 "jdbc/oracle"로 불러온다
3) context.xml 에 정의한 객체는 이름 앞에 접두사를 붙여야 한다. "java:comp/env/"
4) Object 타입을 반환하기 때문에 좌우의 자료형을 맞추기 위해 다운캐스팅 한다 (이후 예외 처리)
package day14;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class MemberDAO {
private Context init;
private DataSource ds;
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
private static MemberDAO instance = new MemberDAO(); // MemberDAO의 객체는 오직 하나뿐이다
public static MemberDAO getInstance() { // 객체를 반환하는 함수 getInstance()는 외부에서 호출가능
return instance;
}
private MemberDAO() { // 생성자 외부 호출 금지
try {
init = new InitialContext(); // context.xml 불러오기
ds = (DataSource) init.lookup("java:comp/env/jdbc/oracle"); // context 내부 DataSource 불러오기
} catch (NamingException e) {
e.printStackTrace();
}
}
private MemberDTO mapping(ResultSet rs) throws SQLException {
MemberDTO dto = new MemberDTO();
dto.setEmail(rs.getString("email"));
dto.setGender(rs.getString("gender"));
dto.setUserid(rs.getString("userid"));
dto.setUsername(rs.getString("username"));
dto.setUserpw(rs.getString("userpw"));
return dto;
}
private void close() {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
} catch(SQLException e) {}
}
// DB 버전정보 (접속 여부 확인하기)
public String getVersion() {
String version = null;
String sql = "select banner from v$version";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
version = rs.getString("banner");
}
} catch (SQLException e) {
e.printStackTrace();
version = e.getMessage();
} finally { close(); }
return version;
}
// Member 목록을 반환하는 함수 (list 페이지)
public List<MemberDTO> selectList() {
ArrayList<MemberDTO> list = new ArrayList<>();
String sql = "select * from member order by userid";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
MemberDTO dto = mapping(rs);
list.add(dto);
}
} catch (SQLException e) {
e.printStackTrace();
} finally { close(); }
return list;
}
// 사용자 입력값을 테이블에 추가하는 함수 (join-action 페이지)
public int insert(MemberDTO dto) {
int row = 0;
String sql = "insert into member (userid, userpw, username, gender, email)"
+ " values (?, ?, ?, ?, ?)";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getUserid());
pstmt.setString(2, dto.getUserpw());
pstmt.setString(3, dto.getUsername());
pstmt.setString(4, dto.getGender());
pstmt.setString(5, dto.getEmail());
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally { close(); }
return row;
}
// 입력값(id, password)를 전달받아서 일치하는 계정 하나를 반환하는 함수
// login 페이지
public MemberDTO login(MemberDTO dto) {
MemberDTO login = null;
String sql = "select * from member where userid = ? and userpw = ?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getUserid());
pstmt.setString(2, dto.getUserpw());
rs = pstmt.executeQuery();
while(rs.next()) {
login = mapping(rs);
}
} catch (SQLException e) {
e.printStackTrace();
} finally { close(); }
return login;
}
}
가장 에러를 많이 띄웠던 부분
String sql = "insert into member (userid, userpw, username, gender, email)"
+ " values (?, ?, ?, ?, ?)";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getUserid());
pstmt.setString(2, dto.getUserpw());
pstmt.setString(3, dto.getUsername());
pstmt.setString(4, dto.getGender());
pstmt.setString(5, dto.getEmail());
row = pstmt.executeUpdate();
}
-> 매개변수의 개수와 타입을 일치하게 받아야하기 때문에
sql 구문에 오타가 났거나, 순서대로 받지 않으면 에러가 날 확률이 100000% !!
필요한 jsp 페이지 생성
: header / login / login-action / logout / list / join / join-action / index / delete
페이지를 많이 만들때에는 항상 header 를 만들어서 사용하자
join.jsp
: 사용자에게 보이는 화면, 회원가입
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<section>
<h3>회원가입 (join.jsp)</h3>
<form method="POST" action="join-action.jsp">
<p><input type="text" name="userid" placeholder="ID" required autofocus></p>
<p><input type="password" name="userpw" placeholder="Password" required></p>
<p><input type="text" name="username" placeholder="Name" required></p>
<p><input type="email" name="email" placeholder="foo@bar.com" required></p>
<p>
<label><input type="radio" name="gender" value="남성" required>남성</label>
<label><input type="radio" name="gender" value="여성" required>여성</label>
</p>
<p><input type="submit" value="가입신청"></p>
</form>
</section>
</body>
</html>
join-action.jsp
: 실질적으로 회원가입을 처리하는 페이지
MemberDAO에 insert() 함수를 이용하여 데이터를 추가
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<jsp:useBean id="dto" class="day14.MemberDTO" />
<jsp:setProperty property="*" name="dto" />
<c:set var="row" value="${dao.insert(dto) }" />
${row }
<c:if test="${row != 0 }">
<c:redirect url="/list.jsp" />
</c:if>
<script>
alert('가입이 처리되지 않았습니다')
history.go(-1)
</script>
</body>
</html>
login.jsp
: 사용자에게 보이는 화면
join 페이지에서 회원가입한 다음에
login 페이지에 아이디와 비번을 일치하게 기입하고 제출한다면 로그인 성공
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<section>
<h3>login.jsp</h3>
<form action="login-action.jsp" method="POST">
<p><input type="text" name="userid" placeholder="ID" required autofocus></p>
<p><input type="password" name="userpw" placeholder="password" required></p>
<p><input type="submit" value="로그인"></p>
</form>
</section>
</body>
</html>
login-action.jsp
: 실질적으로 login 처리
사용자가 입력한 아이디와 비번을 dto 라는 이름으로 묶어서
useBean + setProperty 를 통해서 저장
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<jsp:useBean id="dto" class="day14.MemberDTO" />
<jsp:setProperty property="*" name="dto" />
<c:set var="login" value="${dao.login(dto) }" scope="session" />
<c:if test="${not empty login }">
<c:redirect url="/" />
</c:if>
<script>
alert('계정 혹은 패스워드가 일치하지 않습니다')
history.go(-1)
</script>
</body>
</html>
logout.jsp
: 세션을 만료시켜서, 로그인을 해제함
login 이라는 이름의 세션 객체를 remove 태그를 이용하여 삭제한다
로그인이 해제된 다음에는 대문페이지로 리다이렉트
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<section>
<h3>logout.jsp</h3>
<c:remove var="login" scope="session" />
<c:redirect url="/" />
</section>
</body>
</html>
study_review
오늘 같은 부분에서 계속 실수를 했다.
sql 구문과 preparedstatement 객체를 통하여 값을 저장할때 에러를 많이 띄웠다
아직 익숙하지 않은 구조인듯하다
차라리 이 구조를 외워버려야겠다
'java' 카테고리의 다른 글
[ jsp ] 회원 + 게시판 (0) | 2023.12.14 |
---|---|
[ jsp ] 회원기능 구현 (2) - 수정, 삭제 (0) | 2023.12.12 |
[ jsp ] 로그인 세션 (0) | 2023.12.11 |
[ 상속 ] (0) | 2023.12.10 |
[ 백준 2444번 ] 별 찍기 - 7 ( java ) (0) | 2023.12.10 |