딸기말차

[Java web] 6. Mini Project_2 본문

Bootcamp/Java web

[Java web] 6. Mini Project_2

딸기말차 2023. 7. 22. 03:54

엔코아 플레이데이터(Encore Playdata) Backend 2기 백엔드 개발 부트캠프 (playdata.io)

 

백엔드 개발 부트캠프

백엔드 기초부터 배포까지! 매력있는 백엔드 개발자 포트폴리오를 완성하여 취업하세요.

playdata.io


1. 기획

여태 배운 내용을 토대로, 두번째 팀 프로젝트를 진행하였다. 이번 프로젝트는 과거 다른 팀이 진행했던 프로젝트를 벤치마킹하여 진행되었고, 강사님께서 거신 조건은 다음과 같다.
1. 유저 페이지를 구현할 것
2. 관리자 페이지를 구현할 것
3. 일정 / 쪽지 / 결재 기능 중 하나 이상을 구현할 것
 
해당 조건 중 유저 페이지, 관리자 페이지, 결재 기능을 우선 택하였고, 팀과 논의한 결과 1대1 문의 기능과 결제 기능을 추가하여 프로젝트를 설계하게 되었다.

 

프로젝트의 시나리오는 다음과 같다.

1. 클라이언트가 결제가능한 여행 목록을 보고 장바구니에 담기

2. 장바구니에 담아둔 품목을 보고 결제 및 여행신청

3. 관리자가 결제가 완료 된 신청목록에서 여행 승인

4. 1대1 문의가 필요하면 문의함 이용

 

이 중 필자는 유저 페이지 및 관리자 페이지의 회원가입, 로그인, 로그아웃과 결제가 완료 된 아이템을 승인해주는 기능을 맡아 프로젝트를 진행하였다.


2.  DB 설계

해당 기능들의 구현을 위해 설계한 DB 테이블들은 다음과 같다.

 

1. User Table

회원가입에 입력하는 정보들로 아이디, 비밀번호, 이름, 이메일, 전화번호, 가입일자 데이터를 가지고 있고, IDX와 ID를 Primary Key로 지정하여 해당 값을 이용해 조회할 수 있게 구성하였다.

User

2. Admin Table

유저 테이블과 마찬가지로 회원가입에 입력하는 정보들로 구성되어 있고 IDX, ID를 Primary Key로 지정해 해당 값을 이용해 조회할 수 있다.

Admin

3. Item Table

여행이름, 출발지, 도착지, 가격, 구매가능한 총 횟수, 현재 구매 완료 된 횟수, 출발 시간, 도착 시간을 가지고있고 Primary Key로 IDX를 지정하여 해당 값을 이용해 조회할 수 있다.

Item

4. Purchase Table

여행 IDX 및 유저 IDX를 Foreign Key로 지정하여, Item Table과 User Table에 JOIN 쿼리를 통해 접근, 원하는 조건에 맞는 데이터를 조회하기 위한 테이블이다.

Purchase

5. Message Table

발신자, 수신자, 제목, 내용, 발신일, 답신일, 읽음 유무, 답변 유무 정보를 저장할 수 있는 테이블이다. 마찬가지로 Primary Key로 IDX를 지정하여 해당 값을 이용해 조회할 수 있다.

Message


3.  구조 설계

우리가 웹 프로젝트를 실행 시키면, 일반적으로 실행 순서는 다음과 같다.

 

1. 클라이언트의 요청

2. 웹 서버에서 WAS 서버로 클라이언트가 요청한 데이터 및 권한 양도

3. WAS 서버의 Servlet 주소 탐색

4. HTTPServlet request 객체에 데이터를 담아 Servlet으로 이동

5. request 객체 내의 데이터를 이용한 비즈니스 로직 실행

6. 비즈니스 로직의 실행 결과를 RequestDispatcher 객체에 담아 JSP로 전송

7. JSP에서 해당 데이터를 사용해 화면 구성 및 이동


해당 과정을 보면, 데이터의 전송엔 항상 Servlet이 관여하는 것을 볼 수 있다. 물론 JSP에서 다른 JSP로도 데이터를 전송할 수 있지만, JSP는 어디까지나 Java 코드를 사용하는 것을 지원하는 것이지 데이터의 전송을 위한 비즈니스 로직들을 구현하는 것은 객체 지향 설계 원칙에 맞지 않다고 생각한다.

 

JSP는 꼭 필요한 경우가 아니면 화면을 구성하는 기능에만 충실해야 한다고 생각하고, 때문에 설계 시 DB에 접근하는 모든 로직은 Servlet 내에서 DAO 객체를 통해 실행할 수 있도록 구현하였다.

Servlet

1. db 패키지
DB를 연결하기 위해 필요한 MySQLConnector 클래스를 담아두었다.
 

2. vo 패키지
DB 테이블 레코드의 형태를 띈 클래스들을 구현해 담아두었다.


3. dao 패키지
MySQLConnector 클래스를 상속받아 super()를 사용하여 부모 클래스로 접근하여 DB를 연결하고, 비즈니스 로직을 구현한 클래스들을 담아두었다.
 
4. admin 패키지
결제 완료 후 여행을 최종 승인해주는 AdminApproveServlet 클래스를 구현해 담아두었다.
 
5. login 패키지
유저 및 관리자의 메인 페이지를 위한 Servlet과, 로그인을 위한 Servlet, 회원가입을 위한 Servlet를 구현해 담아두었다.

 

Jsp


4.  db Package

db package는 Java 프로젝트를 DB에 연결하는데 사용해야하는 Connector 클래스를 구현해 담아둔 패키지이다.
 
1. MySQLConnector Class
1) DB 접속 정보들
2) 접속을 시행하기 위한 connectMySQL()

3) Statement, PreparedStatement, ResultSet 객체를 닫기 위한 close() 들
 
이 때 접속을 위한 정보들은 누군가 쉽게 접근하면 안되고, fix된 정보이기 때문에 private final을 사용하여 선언하였다.

public class MySQLConnector {
	private final String driver = "com.mysql.cj.jdbc.Driver";
	private final String db_name = "team1_travel";
	private final String url = "jdbc:mysql://localhost:3306/" + db_name
			+ "?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
	private final String id_mysql = "root";
	private final String pw_mysql = "0000";

	public Connection conn = null; // MySQL 접속 결과(상태) 저장

	public MySQLConnector() {
		this.connectMySQL();
	}	
	
	private void connectMySQL() {
		try {
			Class.forName(driver);
			System.out.println("driver load 성공");
			conn = DriverManager.getConnection(url, id_mysql, pw_mysql);
			System.out.println("MySQL 접속 성공");

		} catch (ClassNotFoundException e) {
			System.out.println("ClassNotFoundException: " + e.getMessage());
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		}
	}

	public void close(Statement stmt, ResultSet rs) {
		try {
			rs.close();
			stmt.close();
		} catch (SQLException e) {
			System.out.println("Close SQLException: " + e.getMessage());
		}
	}

	public void close(PreparedStatement pstmt) {
		try {
			pstmt.close();
		} catch (SQLException e) {
			System.out.println("Close SQLException: " + e.getMessage());
		}
	}

	public void close(PreparedStatement pstmt, ResultSet rs) {
		try {
			rs.close();
			pstmt.close();
		} catch (SQLException e) {
			System.out.println("Close SQLException: " + e.getMessage());
		}
	}
}

5.  vo Package

vo package는 DB Table의 레코드에 맞는 Java 클래스들을 구현한 패키지이다.

해당 클래스는 DB에서 가져온 데이터를 setter를 통해 저장하거나, 저장 된 데이터를 getter를 통해 가져올 수 있어야 비즈니스 로직을 실행할 수 있기 때문에 getter 및 setter를 함께 구현해 주었다.


1. UserVO

public class UserVO {
	private int userIdx;
	private String userId;
	private String userPw;
	private String userName;
	private String userEmail;
	private String userTel;
	private String userRegDate;
	
	public UserVO() {
	}
	
	public UserVO(int userIdx, String userId, String userPw, String userName, String userEmail, String userTel,
			String userRegDate) {
		super();
		this.userIdx = userIdx;
		this.userId = userId;
		this.userPw = userPw;
		this.userName = userName;
		this.userEmail = userEmail;
		this.userTel = userTel;
		this.userRegDate = userRegDate;
	}

	public int getUserIdx() {
		return userIdx;
	}

	public void setUserIdx(int userIdx) {
		this.userIdx = userIdx;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserPw() {
		return userPw;
	}

	public void setUserPw(String userPw) {
		this.userPw = userPw;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}

	public String getUserTel() {
		return userTel;
	}

	public void setUserTel(String userTel) {
		this.userTel = userTel;
	}

	public String getUserRegDate() {
		return userRegDate;
	}

	public void setUserRegDate(String userRegDate) {
		this.userRegDate = userRegDate;
	}
}

 
2. AdminVO

public class AdminVO {
	private int adminIdx;
	private String adminId;
	private String adminPw;
	private String adminName;
	private String adminEmail;
	private String adminTel;
	private String adminRegDate;
	
	public AdminVO() {
	}

	public AdminVO(int adminIdx, String adminId, String adminPw, String adminName, String adminEmail, String adminTel,
			String adminRegDate) {
		this.adminIdx = adminIdx;
		this.adminId = adminId;
		this.adminPw = adminPw;
		this.adminName = adminName;
		this.adminEmail = adminEmail;
		this.adminTel = adminTel;
		this.adminRegDate = adminRegDate;
	}

	public int getAdminIdx() {
		return adminIdx;
	}

	public void setAdminIdx(int adminIdx) {
		this.adminIdx = adminIdx;
	}

	public String getAdminId() {
		return adminId;
	}

	public void setAdminId(String adminId) {
		this.adminId = adminId;
	}

	public String getAdminPw() {
		return adminPw;
	}

	public void setAdminPw(String adminPw) {
		this.adminPw = adminPw;
	}

	public String getAdminName() {
		return adminName;
	}

	public void setAdminName(String adminName) {
		this.adminName = adminName;
	}

	public String getAdminEmail() {
		return adminEmail;
	}

	public void setAdminEmail(String adminEmail) {
		this.adminEmail = adminEmail;
	}

	public String getAdminTel() {
		return adminTel;
	}

	public void setAdminTel(String adminTel) {
		this.adminTel = adminTel;
	}

	public String getAdminRegDate() {
		return adminRegDate;
	}

	public void setAdminRegDate(String adminRegDate) {
		this.adminRegDate = adminRegDate;
	}
}


3. ApproveVO

public class ApproveVO {
	private int trvIdx;
	private String trvName;
	private String trvDepart;
	private String trvDest;
	private int trvPrice;
	private int trvTcnt;
	private int trvCcnt;
	private String trvDepDate;
	private String trvDestDate;
	private int userIdx;
	private String userName;

	public ApproveVO() {
	}

	public int getTrvIdx() {
		return trvIdx;
	}

	public void setTrvIdx(int trvIdx) {
		this.trvIdx = trvIdx;
	}

	public String getTrvName() {
		return trvName;
	}

	public void setTrvName(String trvName) {
		this.trvName = trvName;
	}

	public String getTrvDepart() {
		return trvDepart;
	}

	public void setTrvDepart(String trvDepart) {
		this.trvDepart = trvDepart;
	}

	public String getTrvDest() {
		return trvDest;
	}

	public void setTrvDest(String trvDest) {
		this.trvDest = trvDest;
	}

	public int getTrvPrice() {
		return trvPrice;
	}

	public void setTrvPrice(int trvPrice) {
		this.trvPrice = trvPrice;
	}

	public int getTrvTcnt() {
		return trvTcnt;
	}

	public void setTrvTcnt(int trvTcnt) {
		this.trvTcnt = trvTcnt;
	}

	public int getTrvCcnt() {
		return trvCcnt;
	}

	public void setTrvCcnt(int trvCcnt) {
		this.trvCcnt = trvCcnt;
	}

	public String getTrvDepDate() {
		return trvDepDate;
	}

	public void setTrvDepDate(String trvDepDate) {
		this.trvDepDate = trvDepDate;
	}

	public String getTrvDestDate() {
		return trvDestDate;
	}

	public void setTrvDestDate(String trvDestDate) {
		this.trvDestDate = trvDestDate;
	}

	public int getUserIdx() {
		return userIdx;
	}

	public void setUserIdx(int userIdx) {
		this.userIdx = userIdx;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
}

6.  dao Package

DAO 객체는 구현한 VO 객체와 Query를 이용해 직접 DB에 접근하게되는 객체이다. 

해당 구현을 위해 우선 db package 내 Connector를 상속받아, super() 키워드를 사용하여 Connector 클래스의 생성자에 접근, DB 연결 메서드를 실행하였다.

이 후 필요한 Query 메서드를 구현하고, 필요한 Servlet 내에서 DAO 객체를 생성해 메서드를 호출하였다.

 

1. UserDAO

1) selectUserDAO() : 로그인 시 ID, PW를 통해 존재하는 User인지 판별

2) selectUserSignUp() : 회원가입 시 이미 존재하는 회원인지를 확인

3) insertUserSignUp() : 회원가입 form에 입력한 정보를 insert

public class UserDAO extends MySQLConnector {
	public UserDAO() {
		super();
	}
	
	public UserVO selectUserDAO(String id, String pw) {
		UserVO user = new UserVO();
		String query = "select * from USER where USERID = ? AND USERPW = ?";

		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.setString(2, pw);
			rs = pstmt.executeQuery();

			while (rs.next()) {
				user.setUserIdx(rs.getInt("USERIDX"));
				user.setUserId(rs.getString("USERID"));
				user.setUserPw(rs.getString("USERPW"));
				user.setUserName(rs.getString("USERNAME"));
				user.setUserEmail(rs.getString("USEREMAIL"));
				user.setUserTel(rs.getString("USERTEL"));
				user.setUserRegDate(rs.getString("USERREGDATE"));
			}
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt, rs);
		}
		return user;
	}
	
	public boolean selectUserSignUp(String inputId) {
		String query = "select USERID from USER where USERID = ?";
		String id = "";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, inputId);
			rs = pstmt.executeQuery();
			
			while (rs.next()) {
				id = rs.getString("USERID");
				System.out.println(id);
				if (id != null)
					return true;
			}
			
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt);
		}
		return false;
	}

	public void insertUserSignUp(UserVO user) {
		String query = "insert into USER values (null, ?, ?, ?, ?, ?, now())";

		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, user.getUserId());
			pstmt.setString(2, user.getUserPw());
			pstmt.setString(3, user.getUserName());
			pstmt.setString(4, user.getUserEmail());
			pstmt.setString(5, user.getUserTel());
			pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt);
		}
	}
}

 

2. AdminDAO

1) selectAdminDAO() : 로그인 시 ID, PW를 통해 존재하는 Admin인지 판별

2) selectAdminSignUp() : 회원가입 시 이미 존재하는 회원인지를 확인

3) insertAdminSignUp() : 회원가입 form에 입력한 정보를 insert

public class AdminDAO extends MySQLConnector {
	public AdminDAO() {
		super();
	}
	
	public AdminVO selectAdminDAO(String id, String pw) {
		AdminVO admin = new AdminVO();
		String query = "select * from ADMIN where ADMINID = ? AND ADMINPW = ?";

		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.setString(2, pw);
			rs = pstmt.executeQuery();

			while (rs.next()) {
				admin.setAdminIdx(rs.getInt("ADMINIDX"));
				admin.setAdminId(rs.getString("ADMINID"));
				admin.setAdminPw(rs.getString("ADMINPW"));
				admin.setAdminName(rs.getString("ADMINNAME"));
				admin.setAdminEmail(rs.getString("ADMINEMAIL"));
				admin.setAdminTel(rs.getString("VTEL"));
				admin.setAdminRegDate(rs.getString("ADMINREGDATE"));
			}
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt, rs);
		}
		return admin;
	}
	
	public boolean selectAdminSignUp(String inputId) {
		String query = "select ADMINID from ADMIN where ADMINID = ?";
		String id = "";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, inputId);
			rs = pstmt.executeQuery();
			
			while (rs.next()) {
				id = rs.getString("ADMINID");
				System.out.println(id);
				if (id != null)
					return true;
			}
			
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt);
		}
		return false;
	}
	
	public void insertAdminSignUp(AdminVO admin) {
		String query = "insert into ADMIN values (null, ?, ?, ?, ?, ?, now())";

		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, admin.getAdminId());
			pstmt.setString(2, admin.getAdminPw());
			pstmt.setString(3, admin.getAdminName());
			pstmt.setString(4, admin.getAdminEmail());
			pstmt.setString(5, admin.getAdminTel());
			pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt);
		}
	}
}

 

3. ApproveDAO

1) selectApproveDAO() :  item 테이블, user 테이블을 JOIN하여 결제완료 된 상품을 SELECT

2) updateApprovePurchase() : 승인 버튼을 누를 시 purchase 테이블의 승인여부를 update

3) updateApproveItem() : 승인 버튼을 누를 시 item 테이블의 승인완료 된 상품 개수를 update

public class ApproveDAO extends MySQLConnector {

	public ApproveDAO() {
		super();
	}
	
	public ArrayList<ApproveVO> selectApproveDAO() {
		ArrayList<ApproveVO> approves = new ArrayList<ApproveVO>();
		ApproveVO approve = new ApproveVO();
		String query = "select DISTINCT i.trvidx, i.trvname, i.trvdepart, i.trvdest, i.trvprice, i.trvtcnt, i.trvccnt, i.trvdepdate, i.trvdestdate, u.useridx, u.username \r\n"
				+ "from PURCHASE as p LEFT JOIN ITEM as i on p.trvidx = i.trvidx AND p.trvpay=true AND p.trvapprove = false LEFT JOIN USER as u on p.useridx = u.useridx where i.trvidx is not null;";

		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.createStatement();
			rs = stmt.executeQuery(query);

			while (rs.next()) {
				approve.setTrvIdx(rs.getInt("TRVIDX"));
				approve.setTrvName(rs.getString("TRVNAME"));
				approve.setTrvDepart(rs.getString("TRVDEPART"));
				approve.setTrvDest(rs.getString("TRVDEST"));
				approve.setTrvPrice(rs.getInt("TRVPRICE"));
				approve.setTrvTcnt(rs.getInt("TRVTCNT"));
				approve.setTrvCcnt(rs.getInt("TRVCCNT"));
				approve.setTrvDepDate(rs.getString("TRVDEPDATE"));
				approve.setTrvDestDate(rs.getString("TRVDESTDATE"));
				approve.setUserIdx(rs.getInt("USERIDX"));
				approve.setUserName(rs.getString("USERNAME"));
				approves.add(approve);
			}
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(stmt, rs);
		}
		return approves;
	}

	public void updateApprovePurchase(int trvIdx, int userIdx) { // 테이블 데이터 수정
		String query = "update purchase set TRVAPPROVE = TRUE where TRVIDX = ? AND USERIDX = ?";

		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, trvIdx);
			pstmt.setInt(2, userIdx);
			pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt);
		}
	}
	
	public void updateApproveItem(int trvIdx) { // 테이블 데이터 수정
		String query = "update ITEM set TRVCCNT = case when TRVCCNT >= TRVTCNT then TRVTCNT "
				+ "else TRVCCNT + 1 END where TRVIDX = ?";

		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, trvIdx);
			pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
		} finally {
			close(pstmt);
		}
	}
}

7.  admin Package

결제 완료된 상품들을 승인해주는 기능을 위한 Servlet을 구현한 패키지이다.
 
1. AdminApproveServlet
1) DB 연결 및 Query 메서드를 실행하기 위한 DAO 객체 생성

2) 승인 대기 상품목록을 가져오기 위한 ApproveVO List 생성

3) Header의 상품승인 a 태그를 누를 시 : doGet() 을 통해 승인 대기 상품목록을 불러와 JSP로 전달

4) 승인 버튼을 누를 시 : doPost() 를 통해 purchase, item 테이블에 승인여부 update

@WebServlet("/adminApprove")
public class AdminApproveServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private final ApproveDAO approveDAO = new ApproveDAO();
	private List<ApproveVO> approves = new ArrayList<ApproveVO>();

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		approves = approveDAO.selectApproveDAO();
		
		request.setAttribute("approves", approves);
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("admin/adminApprove.jsp");
		requestDispatcher.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		approveDAO.updateApprovePurchase(Integer.parseInt(request.getParameter("trvIdx")), Integer.parseInt(request.getParameter("userIdx")));
		approveDAO.updateApproveItem(Integer.parseInt(request.getParameter("trvIdx")));
		
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter outs = response.getWriter();
		outs.println("<script>alert('승인 되었습니다.'); location.href = 'adminApprove';</script>");
		outs.flush();
	}
}

7.  login Package

login package는 유저 및 관리자의 메인페이지와 회원가입, 로그인, 로그아웃 기능을 위한 Servlet을 구현한 패키지 이다.
 
1. UserMainServlet
1) index.jsp에서 userMain이라는 servlet 주소로 redirect 시 해당 servlet으로 들어와, userMain.jsp로 이동한다.

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

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("userMain.jsp");
		requestDispatcher.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

 
2. AdminMainServlet
userMain.jsp의 우하단에 있는 admin page 버튼을 누를 시, 해당 servlet 주소로 들어와 adminMain.jsp로 이동한다.

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

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("admin/adminMain.jsp");
		requestDispatcher.forward(request, response);
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

 

3. UserLoginServlet

1) 로그인 버튼을 누를 시 : doGet()으로 들어와 ID와 PW를 입력하는 페이지로 이동한다.

2) form 태그 내의 ID와 PW를 입력 후 : doPost()로 들어와 올바른 ID, PW인지 검증한다.

@WebServlet("/userLogin")
public class UserLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private final UserDAO userDAO = new UserDAO();
    private UserVO user = new UserVO();  
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("login/userLogin.jsp");
		requestDispatcher.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		user = userDAO.selectUserDAO(request.getParameter("id"), request.getParameter("pw"));
	
		if (user.getUserId() == null) {
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter outs = response.getWriter();
			outs.println("<script>alert('ID 혹은 PW가 다릅니다.'); location.href='userMain';</script>");
			outs.flush();
		}
		else {
			HttpSession session = request.getSession();
			session.setAttribute("user", user);
			response.sendRedirect("userMain");
		}
	}
}

 

4. AdminLoginServlet

1) 로그인 버튼을 누를 시 : doGet()으로 들어와 ID와 PW를 입력하는 페이지로 이동한다.

2) form 태그 내의 ID와 PW를 입력 후 : doPost()로 들어와 올바른 ID, PW인지 검증한다.

@WebServlet("/adminLogin")
public class AdminLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private final AdminDAO adminDAO = new AdminDAO();
	private AdminVO admin = new AdminVO();

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("login/adminLogin.jsp");
		requestDispatcher.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		admin = adminDAO.selectAdminDAO(request.getParameter("id"), request.getParameter("pw"));
		if (admin.getAdminId() == null) {
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter outs = response.getWriter();
			outs.println("<script>alert('ID 혹은 PW가 다릅니다.'); location.href='adminMain';</script>");
			outs.flush();
		}
		else {
			HttpSession session = request.getSession();
			session.setAttribute("admin", admin);
			response.sendRedirect("adminMain");
		}
	}
}

 

4. UserSignupServlet

1) 회원가입 버튼을 누를 시 : doGet()으로 들어와 회원가입 페이지로 이동한다.

2) form 태그 내의 회원가입 양식 작성 후 : doPost()로 들어와 중복 된 회원인지 검증한다.

@WebServlet("/userSignup")
public class UserSignupServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private final UserDAO userDAO = new UserDAO();
	private UserVO user = new UserVO();
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("login/userSignup.jsp");
		requestDispatcher.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		user.setUserId(request.getParameter("id"));
		user.setUserPw(request.getParameter("pw"));
		user.setUserName(request.getParameter("name"));
		user.setUserEmail(request.getParameter("email"));
		user.setUserTel(request.getParameter("tel"));

		if (userDAO.selectUserSignUp(request.getParameter("id"))) {
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter outs = response.getWriter();
			outs.println("<script>alert('중복 된 회원입니다.'); location.href='userSignup';</script>");
			outs.flush();
		}
		else {
			userDAO.insertUserSignUp(user);
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter outs = response.getWriter();
			outs.println("<script>alert('회원가입이 완료되었습니다.'); location.href='userMain';</script>");
			outs.flush();
		}
	}
}

 


8.  18일차 후기

이번 프로젝트도 1차와 마찬가지로 일주일 전 미리 공지를 해주셔서, 팀원들과 함께 논의 및 설계를 진행하며 프로젝트를 시작하였다.

Java Web을 배운 이후 처음으로 진행한 프로젝트이기 때문에 아직 미흡한 점이 많았는데, 기간이 길게 잡혀서인지 탄탄한 설계를 세우기보단 어떤 기능을 추가할지에 더 치우치게 되었고, 예상보다 프로젝트의 규모가 너무 커지는 문제가 발생하였다.

 

때문에 각자 맡은 파트를 구현 후 코드를 합치고 보니, 각자 설정한 경로가 달라 모든 페이지에 공통으로 입히려고 준비해둔 Header, Footer, CSS 등이 제대로 적용되지 않고 기능 또한 동작하지 않는 문제가 생겼다.

결국 이 문제를 해결하기 위해 프로젝트 중간에 기능 개발을 멈추고, 현재 페이지에서 다른 페이지로 이동할 때 모든 경로를 Servlet을 통해 이동할 수 있도록 구조를 변경하는 작업을 진행하였다.

 

덕분에 프로젝트 설계 시 데이터의 이동에 관련한 모든부분은 사소한 부분이라도 확실하게 정하고 가야된다는 점을 깨달았다. 단순한 VO 클래스의 변수명 부터 시작해서, SRP를 지키기 위해 Servlet, JSP, DAO 등을 각자의 역할에 맡게 확실히 구분지어 설계하여 다음 프로젝트에서는 중간에 개발을 멈추는 일 없이 진행되도록 노력할 것이다.

'Bootcamp > Java web' 카테고리의 다른 글

[Java web] 8. Oracle JDBC, DispatcherServlet  (0) 2023.07.25
[Java web] 7. Web 복습, Oracle  (0) 2023.07.24
[Java web] 5. EL, JSTL, Java Beans  (1) 2023.07.18
[Java web] 4. Session, JSP tag  (0) 2023.07.15
[Java web] 3. Servlet 실습  (0) 2023.07.14