today_is

[ jsp ] 회원기능 구현 (1) - 회원가입, 로그인, 로그아웃 본문

java

[ jsp ] 회원기능 구현 (1) - 회원가입, 로그인, 로그아웃

ye_rang 2023. 12. 12. 13:48

오늘의 목표

회원테이블을 만들어서

사용자가 사용할 수 있는 회원기능들을 구현해보자!


 

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