회원가입 사이트 만들기
✒️ 2025-05-26 11:08 내용 수정
실습 목표
- Oracle 데이터베이스에 있는 Myuser 테이블에서 회원의 정보를 조회, 추가, 삭제한다.
- 회원 추가 시 이미 존재하는 아이디라면 추가할 수 없도록 설정한다.
실습 흐름
- 데이터베이스에 테이블 및 시퀀스, 필요 시 샘플 데이터 추가
- 데이터베이스에 연결 : context.xml 파일, 라이브러리(JDBC)
- 테이블의 정보를 저장할 DTO 클래스 생성
- 데이터베이스에서 조회, 추가, 삭제를 수행하는 DAO 클래스 생성
- 조회 결과를 확인 및 삭제, 회원 가입할 JSP 생성
- DAO 클래스 객체를 생성하고, JSP와 연결할 Servlet 생성
- Servlet에서 코드 실행 시 결과 확인
DB에 테이블 추가
--시퀀스
CREATE SEQUENCE SEQ_MYUSER_IDX;
--테이블
CREATE TABLE MYUSER(
IDX NUMBER(3) PRIMARY KEY,
NAME VARCHAR2(100) NOT NULL,
ID VARCHAR2(100) NOT NULL, UNIQUE,
PWD VARCHAR2(100) NOT NULL
);
DB 연결
- context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
auth="Container"
name="jdbc/oracle_test"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
factory="org.apache.commons.dbcp.BasicDataSourceFactory"
url="jdbc:oracle:thin:@localhost:1521:xe"
username="계정명" password="비밀번호"
maxActive="20" maxIdle="10" maxWait="1"/>
</Context>
- 라이브러리
- 라이브러리에 lomboc 추가하여 사용
| 파일 |
|---|
| commons-collections-3.2.1.jar |
| commons-dbcp-1.2.2.jar |
| commons-pool-1.4.jar |
| ojdbc8-23.3.0.23.09.jar |
| lomboc.jar |
- service용 DBService.java
package service;
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DBConnection {
static DBConnection db = null;
DataSource ds;
// singleton pattern으로 생성
public static DBConnection getInstance() {
if(db == null) {
db = new DBConnection();
}
return db;
}
// 생성자에서 Context 객체와 DataSource 초기화
public DBConnection() {
try {
InitialContext ic = new InitialContext();
Context ctx = (Context)ic.lookup("java:comp/env");
ds = (DataSource)ctx.lookup("jdbc/oracle_test");
} catch (NamingException e) {
e.printStackTrace();
}
}
// 생성자에서 준비한 정보로 DB에 연결하여 Connection 객체 얻기
public Connection getConnection() {
Connection connec = null;
try {
connec = ds.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
return connec;
}
}
Ajax
- HttpRequest.js
var xhr = null;
function createRequest() {
if (xhr != null) {
return;
}
if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP"); // IE 환경
} else {
xhr = new XMLHttpRequest(); // 기타 브라우저 환경
}
}
function sendRequest(url, param, callback, method) {
// HttpRequest 생성
createRequest();
// 전송 타입 구분
var httpMethod = (method != 'POST' && method != 'post') ? 'GET' : 'POST';
// 파라미터 구분
var httpParam = (param == null || param == '') ? null : param;
// 접근 url
var httpURL = url;
// 요청 방식이 GET이고 전달할 파라미터가 있다면 새 url 경로 제작
if (httpMethod == 'GET' && httpParam != null) {
httpURL = httpURL+'?'+httParam;
}
// 서버로 보낼 Ajax 요청 형식
xhr.open(httpMethod, httpURL, true);
// requestHeader 설정 : Content-Type 지정
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 작업이 완료된 후 호출할 callback 메소드 지정
xhr.onreadystatechange = callback;
// Ajax 요청을 서버로 전달
xhr.send(httpMethod == 'POST' ? httpParam : null);
}
DAO와 DTO
- dto
package dto;
import lombok.Data;
@Data
public class UserDTO {
int idx;
String name;
String id;
String pwd;
}
- dao
package dao;
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 dto.UserDTO;
import service.DBService;
public class UserDAO {
static UserDAO single = null;
public static UserDAO getInstance() {
//생성되지 않았으면 생성
if (single == null)
single = new UserDAO();
//생성된 객체정보를 반환
return single;
}
// 회원 정보 조회
public List<UserDTO> selectList() {
List<UserDTO> list = new ArrayList<UserDTO>();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "SELECT * FROM MYUSER ORDER BY IDX DESC";
try {
//1.Connection얻어온다
conn = DBService.getInstance().getConnection();
//2.명령처리객체정보를 얻어오기
pstmt = conn.prepareStatement(sql);
//3.결과행 처리객체 얻어오기
rs = pstmt.executeQuery();
while (rs.next()) {
UserDTO dto = new UserDTO();
dto.setIdx(rs.getInt("idx"));
dto.setName(rs.getString("name"));
dto.setId(rs.getString("id"));
dto.setPwd(rs.getString("pwd"));
//ArrayList추가
list.add(dto);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list;
}
// 회원 추가
public int insert(UserDTO dto) {
int res = 0;
Connection conn = null;
PreparedStatement pstmt = null;
String sql = "INSERT INTO MYUSER VALUES(SEQ_MYUSER_IDX.nextVal, ?, ?, ?)";
try {
//1.Connection획득
conn = DBService.getInstance().getConnection();
//2.명령처리객체 획득
pstmt = conn.prepareStatement(sql);
//3.pstmt parameter 채우기
pstmt.setString(1, dto.getName());
pstmt.setString(2, dto.getId());
pstmt.setString(3, dto.getPwd());
//4.DB로 전송(res:처리된행수)
res = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return res;
}
// 중복 조회
public UserDTO selectOne(String id) {
UserDTO dto = null;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "SELECT * FROM MYUSER WHERE ID=?";
try {
//1.Connection얻어온다
conn = DBService.getInstance().getConnection();
//2.명령처리객체정보를 얻어오기
pstmt = conn.prepareStatement(sql);
//3.pstmt parameter 설정
pstmt.setString(1, id);
//4.결과행 처리객체 얻어오기
rs = pstmt.executeQuery();
if (rs.next()) {
// 1 건이라도 검색되면 null이 아니게 설정
dto = new UserDTO();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return dto;
}
// 회원 제거
public int delete(int idx) {
int res = 0;
Connection conn = null;
PreparedStatement pstmt = null;
String sql = "DELETE FROM MYUSER WHERE IDX=?";
try {
//1.Connection획득
conn = DBService.getInstance().getConnection();
//2.명령처리객체 획득
pstmt = conn.prepareStatement(sql);
//3.pstmt parameter 채우기
pstmt.setInt(1, idx);
//4.DB로 전송(res:처리된행수)
res = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return res;
}
}
Servlet
- 회원 조회
package action;
import java.io.IOException;
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 dao.UserDAO;
import dto.UserDTO;
@WebServlet("/check_id")
public class MemberCheckAction extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// check_id?id=x
String id = request.getParameter("id");
UserDTO dto = UserDAO.getInstance().selectOne(id);
String res = "no";
if (dto == null) {
res = "yes";
}
String result = String.format("[{'res':'%s'}]", res);
response.getWriter().print(result);
}
}
- 회원 리스트
package action;
import java.io.IOException;
import java.util.List;
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 dao.UserDAO;
import dto.UserDTO;
@WebServlet("/member_list")
public class MemberListAction extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 회원 목록 얻어오기
List<UserDTO> list = UserDAO.getInstance().selectList();
// list를 request 영역에 바인딩
request.setAttribute("list", list);
// member_list.jsp에서 el 표현식을 사용할 수 있도록
// 포워딩 지정
RequestDispatcher disp = request.getRequestDispatcher("member_list.jsp");
disp.forward(request, response);
}
}
- 회원 추가
package action;
import java.io.IOException;
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 dao.UserDAO;
import dto.UserDTO;
@WebServlet("/insert")
public class MemberInsertAction extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// insert?id=X&pwd=X&name=X
request.setCharacterEncoding("utf-8");
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String name = request.getParameter("name");
UserDTO dto = new UserDTO();
dto.setId(id);
dto.setPwd(pwd);
dto.setName(name);
int res = UserDAO.getInstance().insert(dto);
if (res >= 1) {
response.sendRedirect("member_list");
}
}
}
- 회원 삭제
package action;
import java.io.IOException;
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 dao.UserDAO;
@WebServlet("/member_del")
public class MemberDelAction extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
int idx = Integer.parseInt(request.getParameter("idx"));
int res = UserDAO.getInstance().delete(idx);
String param = "no";
if (res >= 1) {
param = "yes";
}
String resultStr = String.format("[{'param':'%s'}]", param);
response.getWriter().print(resultStr);
}
}
JSP
- 회원 추가 JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
table{margin:0 auto;}
</style>
<script src="js/HttpRequest.js"></script>
<script type="text/javascript">
// 아이디 중복체크 여부
var b_idCheck = false;
function send(f) {
var id = f.id.value.trim();
var name = f.name.value.trim();
var pwd = f.pwd.value.trim();
// 유효성 검사
if (id == '') {
alert("id를 입력하세요");
return;
}
if (!b_idCheck) {
alert("아이디 중복 체크를 하세요");
return;
}
if (name == '') {
alert("이름을 입력하세요");
return;
}
if (pwd == '') {
alert("비밀번호를 입력하세요");
return;
}
f.method = "POST";
f.action = "insert";
f.submit();
}
function check_id() {
var id = document.getElementById("id").value.trim();
// 유효성 검사
if (id == '') {
alert("id를 입력하세요");
return;
}
// ajax 사용
// 완전히 새로고침하면 textfield의 내용이 사라지므로 일부분만 로딩
var url = "check_id";
var param = "id="+id;
sendRequest(url, param, resultFn, "POST");
}
function resultFn() {
if(xhr.readyState == 4 && xhr.status == 200) {
var data = xhr.responseText;
var json = eval(data);
if(json[0].res == "no") {
alert("이미 사용 중인 아이디 입니다.");
return;
} else {
alert("사용 가능한 아이디 입니다.");
b_idCheck = true;
}
}
}
function che() {
b_idCheck = false;
}
</script>
</head>
<body>
<form>
<table border="1">
<caption>:::회원가입:::</caption>
<tr>
<th>아이디</th>
<td>
<!-- onchange : input 태그의 내용이 변경될 때 발생하는 이벤트 -->
<input name="id" id="id" onchange="che()">
<input type="button" value="중복체크" onclick="check_id()">
</td>
</tr>
<tr>
<th>이름</th>
<td>
<input name="name">
</td>
</tr>
<tr>
<th>비밀번호</th>
<td>
<input type="password" name="pwd">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="button" value="가입" onclick="send(this.form)">
<input type="button" value="취소" onclick="location.href='member_list'">
</td>
</tr>
</table>
</form>
</body>
</html>
- 회원 리스트 JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
table{border-collapse:collapse;
text-align:center;}
th{width:200px; height:60px;}
</style>
<script src="js/HttpRequest.js"></script>
<script type="text/javascript">
function del(idx) {
if (!confirm("삭제하시겠습니까?")) {
return;
}
var url = "member_del";
var param = "idx="+idx;
sendRequest(url, param, resultFn, "POST");
}
function resultFn() {
if(xhr.readyState == 4 && xhr.status == 200) {
var data = xhr.responseText;
var json = eval(data);
if(json[0].param == "no") {
alert("회원 삭제에 실패했습니다.");
} else {
alert("회원 삭제를 성공했습니다.");
}
location.href = "member_list";
}
}
</script>
</head>
<body>
<table border="1">
<tr>
<td colspan="5" align="center">
<input type="button" value="회원가입" onclick="location.href='member_insert_form.jsp';">
</td>
</tr>
<tr>
<th>회원번호</th>
<th>이름</th>
<th>아이디</th>
<th>비밀번호</th>
<th>비고</th>
</tr>
<c:forEach var="dto" items="${list}">
<tr>
<td>${dto.idx}</td>
<td>${dto.name}</td>
<td>${dto.id}</td>
<td>${dto.pwd}</td>
<td>
<input type="button" value="삭제" onclick="del('${dto.idx}');">
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
완성된 모습
-
ListAction Servlet에서 실행하면 회원 정보가 조회된다.
-
회원가입 버튼을 누르고 중복된 아이디를 누른 후에 중복 확인을 하면 경고창이 뜬다.
-
만약 중복 체크를 안하면 가입하지 못하도록 경고가 뜨면서 새로운 창으로 넘어가지지 않는다.
-
중복된 아이디가 아니라면 가입 조건이 충족된다.
-
가입이 완료되면 다시 회원 정보창에 추가된 계정이 보인다.
-
삭제 버튼을 누르면 안내창이 나온다. 확인을 누르면 삭제가 진행된다.
-
삭제가 제대로 진행된 것을 확인할 수 있다.