본문 바로가기
웹 프로그래밍/🥨스낵몰

[자바/mysql/javascript] 웹쇼핑몰 만들기-2.구현2(장바구니, 로그아웃, 관리자 페이지)

by 청량리 물냉면 2021. 7. 27.
반응형

2021.07.27 - [자바] - [자바/mysql/javascript] 웹쇼핑몰 만들기-2.구현(메인화면, 로그인, 회원가입)

 

[자바/mysql/javascript] 웹쇼핑몰 만들기-2.구현(메인화면, 로그인, 회원가입)

1. 메인화면 메인화면에 들어가자마자 제품들이 보이게 구성하였다. 사용자는 메인화면에서 바로 물건을 확인하고 장바구니에 넣고 결제까지 할 수 있다. 상단바에는 다양한 제품을 볼 수 있도

florescene.tistory.com

 

5. 장바구니

< CartDTO.java > --- DTO: Data Transfer Object, 계층 간의 데이터를 교환하는 역할

package UserController;

public class CartDTO {
	private String name;	//과자명
	private int price;		//가격
	private int cnt;		//수량
	
	public CartDTO() {}

	public CartDTO(String name, int price, int cnt) {
		super();
		this.name = name;
		this.price = price;
		this.cnt = cnt;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getCnt() {
		return cnt;
	}

	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	
}

 

 

< CartView.jsp > ---장바구니 목록 보기

<%@page import="java.text.DecimalFormat"%>
<%@page import="UserController.CartDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
ArrayList<CartDTO> cart = null;

Object obj = session.getAttribute("cart");	//세션 객체에서 cart 값을 가져온다.

if(obj == null) {	//세션 정보가 없으면 배열을 생성 : 주문한 제품이 없다
	cart = new ArrayList<CartDTO>();	
} else {			//세션 정보가 있으면 강제로 캐스팅 : 주문한 제품이 있다
	cart = (ArrayList<CartDTO>) obj;
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>장바구니</title>

<script type="text/javascript">


function fnPay(){
	alert("결제 기능을 지원하지 않습니다.");
}

function fnClear(){
	if(confirm("장바구니를 비우시겠습니까?")) {
		location.href = "../pro/CartClear.jsp";	
	}
}

function fnGo(){
	location.href = "../../UserMain.jsp";
}
</script>
</head>
<body>
<div align="center">
	<h3>[장바구니 보기]</h3>
	<table border="1">
		<tr>
			<th>번호</th>
			<th>과자이름</th>
			<th>단가</th>
			<th>주문 수량</th>
			<th>가격</th>
		</tr>
<%
		if(cart.size() == 0) {
%>
		<tr align='center'>
			<td colspan= '5'>
				장바구니에 담긴 상품이 없습니다.
				<a href= '../../UserMain.jsp'>주문하기</a>
			</td>
		</tr>
<%
		} else {
			int totalSum = 0, total = 0;
			DecimalFormat df = new DecimalFormat("₩#,##0");
			for(int i = 0; i < cart.size(); i++) {
				CartDTO dto = cart.get(i);
		%>
		<tr align= 'center'>
			<td><%=(i + 1) %></td>
			<td><%=dto.getName() %></td>
			<td><%=df.format(dto.getPrice()) %></td>
			<td><%=dto.getCnt() %></td>
			<% 
				total = dto.getPrice() * dto.getCnt();
			%>
			<td><%=df.format(total) %></td>
		</tr>
		<% 
			totalSum += total;
		}
		%>
		<tr align = 'center'>
			<td colspan= '4'>
				<input type='button' value='결제하기' onclick='fnPay()' />
				<input type='button' value='장바구니 비우기' onclick='fnClear()' />
				<input type='button' value='쇼핑 계속하기' onclick='fnGo()' />
			</td>
		<td>
		 <%=df.format(totalSum) %>
		 </td>
			</tr>
		<% 
			}//if else
		%>
	</table>
</div>
</body>
</html>

 

<CartPro.jsp> ---장바구니 기능 구현

<%@page import="UserController.CartDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String price = request.getParameter("price");

ArrayList<CartDTO> cart = null;

Object obj = session.getAttribute("cart");	//세션 객체에서 cart 값을 가져온다.

if(obj == null) {	//세션 정보가 없으면 배열을 생성 : 최초 주문한 경우
	cart = new ArrayList<CartDTO>();	
} else {			//세션 정보가 있으면 강제로 캐스팅 : 추가 주문
	cart = (ArrayList<CartDTO>) obj;
}

int pos = -1;	//등록된 제품이 없다
//장바구니 세션에 동일한 제품이 있을 경우 : 수량(cnt) 증가
for(int i = 0; i < cart.size(); i++) {
	CartDTO dto = cart.get(i);
	if(dto.getName().equals(name)) {
		pos = 1;
		dto.setCnt(dto.getCnt() + 1);
		break;
	}
}

//장바구니 세션에 등록된 제품이 없을 경우 : CartDTO 객체를 생성하여 배열에 등록(add())
if(pos == -1) {
	CartDTO dto = new CartDTO();
	dto.setName(name);
	dto.setPrice(Integer.parseInt(price.replace(",", "")));	//1,500 ▶ 1500 : 쉼표 제거 후 정수형으로 랩핑
	dto.setCnt(1);
	cart.add(dto);
}

//cart 세션 객체를 만들어 준다.
session.setAttribute("cart", cart);
%>

<script>
	alert("장바구니에 담았습니다."); 
	location.href = "../../UserMain.jsp"
</script>

 

< CartClear.jsp > ---장바구니 모두 삭제 기능

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
session.getAttribute("cart");
session.removeAttribute("cart");
response.sendRedirect("../../UserMain.jsp");
%>

 

 

(구현 기능 시뮬레이션)

<장바구니 담기> 클릭시

 

클릭 시 팝업창
<장바구니 보기>클릭 시
장바구니에 담은 물건 목록

담고 싶은 물건을 모두 장바구니에 담은 다음 장바구니 보기 버튼을 클릭하면 고객이 담은 물건의 내역이 화면에 뜬다.

결제하기 버튼을 눌렀을 때의 실행 결과이다. 결제기능은 구현하지 않았다.

장바구니 비우기 버튼을 눌렀을 때이다.

장바구니에 담아둔 내역이 초기화되었다.

<쇼핑 계속하기>를 선택한 경우 초기 메인화면으로 돌아가 계속해서 쇼핑을 할 수 있다.

 

 

6. 고객 로그아웃

로그아웃 버튼을 누르면 세션이 종료되고 메인화면의 상단바는 다시 회원가입과 로그인 버튼을 보여준다.

 

 

< LogoutPro.jsp > ---로그아웃 기능

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	// 세션초기화
	session.invalidate();
	// "로그아웃됨"
%>
	<script>
		alert("로그아웃 되었습니다.");
		location.href = "../../UserMain.jsp";
	</script>
</body>
</html>

7. 관리자

정해진 관리자의 아이디와 비밀번호로 로그인을 한다. 별도의 버튼 없이 로그인 버튼으로 로그인하면 시스템에서 아이디와 비밀번호, userType을 토대로 관리자와 일반 고객 로그인을 구분해준다.

 

< LoginPro.jsp > ---2. 로그인 화면 에 올려둔 로그인 구현 jsp 중 일부. 일반고객/관리자가 구분되어 있음.

	try {
    
		...생략
	
		if (rs.next()) { // 아이디있음
			if (pw.equals(rs.getString("PWD"))) {
				session.setAttribute("ID", id);
				
				if(admin.equals(rs.getString("UserType"))){ //관리자
					response.sendRedirect("../../AdminMain.jsp");
					
				} else if (iuser.equals(rs.getString("UserType"))) { //일반 고객
					response.sendRedirect("../../UserMain.jsp");
				}

			} else {

%>
				<script>
					alert("비밀번호를 확인해주세요.");
					history.back();
				</script>		
<%	
			}
		} else {
			// 아이디없음
%>
			<script>
				alert("아이디를 확인해주세요.");
				//location.href = "loginForm.jsp";  // 서버가 요청을 받는다.
				history.back();  // history.go(-1);  // 서버에 요청없이 브라우저에서 자체적으로 처리
			</script>
	
    ...생략
%>

 

 

메인 화면의 상단바에 회원관리 버튼과 상품등록 버튼이 생겼고, 장바구니 버튼이 사라지고 대신 상품정보 수정 기능 버튼이 생겼다.

아직 상품 정보 변경은 구현하지 못했다.

 

 

< AdminMain.jsp > ---관리자 메인

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   
<%@include file="AdminTop.jsp" %>
<%
String[] img ={"ozing.jpeg", "banana.jpeg", "gaesoo.jpeg", "poka.jpeg", "eyejelly.jpeg", "whitehime.jpeg", "milkys.jpeg", "minit.jpg", "ggobuk.jpeg"};
String[] name = {"오징어집", "바나나킥", "헛개수", "포카칩", "눈알젤리", "화이트하임", "밀키스", "미닛메이드", "꼬북칩"};
String[] price = {"1,500", "1,500", "1,700", "1,300", "1,350", "1,400", "500", "1,000", "1,100"};
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SnackMall</title>
<script type="text/javascript">

function ProductModify(name, price) {
	location.href = "contents/admin/ProdModForm.jsp?name=" + name + "&price=" + price;
}

</script>
</head>
<body>
<div align="center">
	<h3>[오늘의 특가]</h3>
	<table border="1">
		<%
		for(int i = 0; i < img.length; i++) {
			if(i % 3 == 0) { 
				out.println("<tr align='center'>");
			}
			out.println("<td>");
				out.println("<table>");
					out.println("<tr align='center'>");
						out.println("<td>");
							out.println("<img src = 'img/" + img[i] + "' width='150' height='150' />");
						out.println("</td>");
					out.println("</tr>");
					
					out.println("<tr align='center'>");
						out.println("<td>");
							out.println("<b>" + name[i] + "</b>");
						out.println("</td>");
					out.println("</tr>");
					
					out.println("<tr align='center'>");
						out.println("<td>");
							out.println("<b>₩" + price[i] + "원</b>");
						out.println("</td>");
					out.println("</tr>");
					
					out.println("<tr align='center'>");
						out.println("<td>");
							//한 줄로 쓰기
							//out.println("<input type='button' value='장바구니 담기' onclick='fnCart(\"" + name[i] + "\", \"" + price[i] + "\")' />");
							//두 줄로 쓰기, 닫는 큰 따옴표와 괄호 옆의 띄어쓰기 필수
							out.println("<input type='button' value='상품정보수정' ");
							out.println("onclick='ProductModify(\"" + name[i] + "\", \"" + price[i] + "\")' />");
						out.println("</td>");
					out.println("</tr>");
				out.println("</table>");
			out.println("</td>");
			if(i % 3 == 2) {
				out.println("</tr>");
			}
		}
		%>	
	</table>
</div>
</body>
</html>

 

< AdminTop.jsp > ---관리자용 헤더. 장바구니 버튼 삭제, 상품정보 수정 기능 버튼 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/TopNav.css">
    <script src="https://kit.fontawesome.com/8351000410.js" crossorigin="anonymous"></script>
    <title>SnackMall</title>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300&display=swap" rel="stylesheet">   
	
</head>

<body>
    <nav class="navbar">
        <div class="navbar_logo">
            <i class="fas fa-cookie-bite"></i>
            <a href="AdminMain.jsp">SnackMall</a>
        </div>

        <ul class="navbar_menu">
            <li><a href="">오늘의 특가</a></li>
            <li><a href="">인기상품</a></li>
            <li><a href="">과자</a></li>
            <li><a href="">초콜릿/사탕/껌</a></li>
            <li><a href="">음료</a></li>
            <li><a href="">수입과자</a></li>
        </ul>

        <ul class="navbar_usermenu">
            <li><a href="contents/admin/AdminUserList.jsp">회원관리</a></li>
            <li><a href="contents/admin/ProdModForm.jsp">상품등록</a></li>
            <li><a href="contents/pro/LogoutPro.jsp">로그아웃</a></li>
        </ul>

        <ul class="navbar_icons">
            <li><i class="fab fa-twitter-square"></i></li>
            <li><i class="fab fa-facebook-square"></i></li>
            <li><i class="fab fa-instagram"></i></li>
        </ul>

        <a href="#" class="navbar_toggleBtn">   
            <i class="fas fa-bars"></i>
        </a>
    </nav>   
    
    <script> //윈도우 창의 사이즈를 줄였을 시 나오는 햄버거 모양 토글바
	const toggleBtn = document.querySelector('.navbar_toggleBtn');
	const menu = document.querySelector('.navbar_menu');
	const icons = document.querySelector('.navbar_icons');
	
	toggleBtn.addEventListener('click',()=>{
	    menu.classList.toggle('active');
	    icons.classList.toggle('active');
	});
	</script>
	
</body>
</html>

 

회원관리 페이지의 모습이다. 데이터 베이스에 저장된 고객 정보를 모두 열람하고 삭제 및 수정할 수 있다.

 

< AdminUserList.jsp > ---회원목록 보기(데이터베이스에서 목록을 가져옴)

<!-- /* AdminUserList.jsp */  -->

<%@ page contentType="text/html;charset=UTF-8" import="java.sql.*" %>

<%

Class.forName("com.mysql.jdbc.Driver");
String DB_URL = "jdbc:mysql://localhost:3306/snackmall?characterEncoding=UTF-8&serverTimezone=UTC";
String DB_USER = "root";
String DB_PASSWORD= "23er";

Connection conn= null;
Statement stmt = null;
ResultSet rs   = null;

try {
    conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
    stmt = conn.createStatement();
    String query = "SELECT UserType, ID, PWD, UserName, Email, Contact, Address FROM login_db"; // DB에 전송할 쿼리문 생성 목록을 나타내기 위해 SELECT문을 사용했습니다. 
    rs = stmt.executeQuery(query);
%>

<b><font size="5" color="gray">전체 회원 목록</font></b>
<br><br>
<%-- 입력된 값을 추출한다. --%>
<table border="1" cellspacing="0">
	<tr>
		<th>사용자 유형</th>
		<th>아이디</th>
		<th>비밀번호</th>
		<th>이름</th>
		<th>이메일</th>
		<th>연락처</th>
		<th>주소</th>
		
		<th>비고 </th>	
	</tr>
	
<%
    while(rs.next()) {
    	if(rs.getString("UserType").equals("Admin")) continue;
%>	<tr>
		<td><%=rs.getString("UserType")%></td>
		<td><%=rs.getString("ID")%></td>
		<td><%=rs.getString("PWD") %></td>
		<td><%=rs.getString("UserName") %></td>
		<td><%=rs.getString("Email") %></td>
		<td><%=rs.getString("Contact") %></td>
		<td><%=rs.getString("Address")%></td>
		
		<td> 
		<input type="button" value="삭제" 
		onClick="location.href='AdminUserDel.jsp?ID=<%=rs.getString("ID")%>'"> <!-- AdminUserDel.jsp링크를 이용하여 해당 테이블의 데이터들을 삭제 -->
		<input type="button" value="수정" 
		onClick="location.href='AdminModForm.jsp?ID=<%=rs.getString("ID")%>'"> <!-- AdminUserMdfForm.jsp로 이동하여 해당 테이블의 데이터값들을 수정 -->
		</td>
	</tr>
<%

} // end while

%></table>
	<br>
	<input type="button" value=" 확 인 " 
	onClick="location.href='../../AdminMain.jsp'">


<%
	rs.close();     // ResultSet 종료
    stmt.close();     // Statement 종료
    conn.close(); 	// Connection 종료

} catch (SQLException e) { // 예외처리
      out.println("err:"+e.toString());
} 

%>

 

#회원정보 삭제

김자바라는 고객의 목록을 데이터베이스에서 삭제했다.

데이터 베이스에도 삭제내용이 잘 반영되었다.

 

 

< AdminUserDel.jsp > ---회원목록에서 해당 회원 삭제. 데이터베이스에서 회원 정보를 삭제

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.sql.*" %>

<%
	request.setCharacterEncoding("UTF-8");
	String id = request.getParameter("ID");
	
	try {
		
		Class.forName("com.mysql.jdbc.Driver");
		String DB_URL = "jdbc:mysql://localhost:3306/snackmall?characterEncoding=UTF-8&serverTimezone=UTC";
		
		String userName="root";
		String password="23er";
		
		Connection con = DriverManager.getConnection(DB_URL, userName, password);

		String sql = "DELETE FROM login_db WHERE ID=?";

		PreparedStatement pstmt = con.prepareStatement(sql); 
		pstmt.setString(1, id);

		pstmt.executeUpdate();

		pstmt.close();
		con.close();
	}

	catch(ClassNotFoundException e) {
		out.println(e);
	}

	catch(SQLException e) {
		out.println(e);
	}
	response.sendRedirect("AdminUserList.jsp");
%>

 

 

 

#회원정보 수정

 

회원정보 수정 버튼을 누르면 기본적으로 고객이 입력해둔 고객정보가 보이고, 관리자가 이를 수정 가능하게 구현했다. Id는 메인 키 값이기 때문에 readonly를 이용해 수정할 수 없도록 하였다.

수정버튼을 누르면 바로 회원 목록으로 이동한다. 아쉽게도 수정항목이 반영되지 않은 모습이다. 해당 기능은 구현에 실패하였다.

 

 

< AdminModForm.jsp >

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" 
    import="java.sql.*" %>
    
<!DOCTYPE html>
<%@ page import = "java.sql.*" %>
<html>
<head>
<meta charset="EUC-KR">
<title>회원수정</title>
</head>
<body>
    <% request.setCharacterEncoding("euc-kr"); 
//회원정보페이지에서 수정버튼 클릭시 보내진 id값 받기    
    request.setCharacterEncoding("euc-kr");
    String id = request.getParameter("ID");
//객체참조변수 선언    
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
//DB 드라이버 로딩    
    Class.forName("com.mysql.jdbc.Driver");
//DB 연결, 객체생성    
    conn = DriverManager.getConnection
    ("jdbc:mysql://localhost:3306/snackmall?characterEncoding=UTF-8&serverTimezone=UTC", "root", "23er");
//쿼리문 준비    
    pstmt = conn.prepareStatement("SELECT ID,PWD,UserName,Email, Contact,Address FROM login_db WHERE ID=?");
    pstmt.setString(1, id);
//쿼리문 실행    
    rs = pstmt.executeQuery();
//결과값 사용    
    rs.next();
%>       
<h1>회원정보수정</h1>
	<form action="AdminModPro.jsp" method="post">
		id <input type="text" name="id" value=<%=rs.getString("ID")%> readonly><br>
		패스워드 변경 <input type="password" name="pwd" value=<%=rs.getString("PWD")%>><br>
		이   름  변  경 <input type="text" name="username" value=<%=rs.getString("UserName")%>><br>
		이 메 일 변 경 <input type="text" name="email" value=<%=rs.getString("Email")%>><br>
		연 락 처 변 경 <input type="text" name="contact" value=<%=rs.getString("Contact")%>><br>
		주   소  변  경 <input type="text" name="address" value=<%=rs.getString("Address")%>><br>
		<input type="submit" value="수정">
	</form>
</body>
</html>

 

< AdminModPro.jsp >

<!-- /* AdminUserList.jsp */  -->

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.sql.*" %>
    
    <%
	  request.setCharacterEncoding("utf-8");
	  // id passwd name가져오기
	  String id = request.getParameter("ID");
	  String pwd = request.getParameter("PWD");
	  String username = request.getParameter("UserName");
	  String email = request.getParameter("Email");
	  String contact = request.getParameter("Contact");
	  String address = request.getParameter("Address");
	  
	    //객체참조변수 선언    
	    Connection conn = null;
	    PreparedStatement pstmt = null;
	  
	   // 1단계 드라이버로더
	   Class.forName("com.mysql.jdbc.Driver");
	   
	// 2단계 디비연결
	   String DB_URL = "jdbc:mysql://localhost:3306/snackmall?characterEncoding=UTF-8&serverTimezone=UTC";
	   String DB_USER = "root";
	   String DB_PASSWORD= "23er";
	   conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
	   
	   pstmt = conn.prepareStatement("UPDATE login_db SET PWD=?, UserName=?, Email=?, Contact=?, Address=? WHERE ID=?");

	   pstmt.setString(1, pwd);
	   pstmt.setString(2, username);
	   pstmt.setString(3, email);
	   pstmt.setString(4, contact);
	   pstmt.setString(5, address);
	   pstmt.setString(6, id);
	
		int result = pstmt.executeUpdate();

		System.out.println(result + "<-- result");
 
		pstmt.close();
		conn.close(); 
		
 		response.sendRedirect("AdminUserList.jsp");
%>

 

관리자가 로그아웃을 하면 초기 메인페이지로 돌아온다.

관리자가 로그아웃하고 난 후의 화면

 

 

 

참고자료

dao vs dto: https://velog.io/@ohzzi/Entity-DAO-DTO%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C

 

Entity, DAO, DTO가 무엇이며 왜 사용할까?

개인적으로 Spring Boot를 가지고 CRUD를 구현한 Todo-list를 만들어면서, Spring Data JPA를 사용하게 되었다. JPA를 사용하면서, 생전 처음 보는 Entity, DAO, DTO 개념을 사용하게 되었는데, 앞으로 계속 많이

velog.io

 

전체 소스링크

https://github.com/Yoonyesol/Snack-Mall.git

 

GitHub - Yoonyesol/Snack-Mall

Contribute to Yoonyesol/Snack-Mall development by creating an account on GitHub.

github.com

 

반응형