'회원관리 웹 어플리케이션' 포스팅 에서 이어지는 포스팅입니다.
> 위 회원관리 웹 어플리케이션을 이용하여, 장바구니 웹 어플리케이션을 만들기 위한 준비 ! <
1. 기존 프로젝트 (위 포스팅에서 작성된 프로젝트) 복사 > 붙여넣기
2. 새로 복제된 프로젝트의 이름 변경 (webstudy35-jstl-item-inst -> webstudy36-cart 로)
3. webstudy36-cart 프로젝트에 오른쪽 마우스 클릭해서 properties 들어가기
4. Location 오른쪽 끝 옆 파일 이모티콘 클릭
5. webstudy36-cart > .setting > org.eclipse.wst.common.component 열기
6. 아래 세 부분을 'webstudy36-cart'로 변경
7. 다시 이클립스로 돌아와 'webstudy36-cart' 오른쪽 마우스 클릭 > Refresh
[ 요구사항 ]
1. 웹 어플리케이션 시작 시, 첫 화면에 아이템 리스트가 제공된다.
2. 비로그인 상태에서는 아이템 리스트와 아이템 상세정보를 조회할 수 있다.
3. 로그인 상태에서는 로그아웃과 상품 등록이 가능하다.
[ 추가기능 ]
4. 로그인하면 상단부 Header 부분에 장바구니 링크가 제공된다.
5. 아이템 상세보기에서는 비로그인 상태와 다르게, 로그인한 사용자에 한애 하단부에 장바구니 담기 버튼이 제공된다.
- 장바구니는 회원과 1:1 관계이다.
6. 장바구니에는 상품을 여러 개 담을 수 있고,
상품 아이템이 중복될 경우 '이미 장바구니에 담은 상품입니다'라는 메세지를 보여주고, 상품 아이템을 담아주지 않는다.
7. '장바구니 담기' 버튼을 누를 경우,
- '장바구니에 담으시겠습니까?' 메세지에서
- '확인'을 누르면, 장바구니에 아이템을 담고
> '장바구니에 추가! 장바구니로 이동하시겠습니까?'
- '확인'누르면 장바구니로 이동하고,
- '취소'누르면 장바구니로 이동하지 않는다.
8. 상단부 장바구니 링크를 누르면 회원이 담은 상품 아이템 리스트가 제공된다.
- 상품 아이템 리스트에서는 상품 아이템 번호, 상품명, 제조사, 가격이 제공되고,
아이템 당 '삭제' 버튼이 제공된다.
> '삭제' 버튼을 누른 경우 : '장바구니에서 상품을 삭제하시겠습니까?' 여부를 확인한 후
- '확인'을 누르면, 해당 상품 아이템을 삭제 한 후, 다시 장바구니를 보여준다.
- 장바구니 가장 하단부에 총액이 제공된다. (장바구니에 담은 아이템 총액)
[ UseCase Diagram ]
[ 구현 코드 ]
Model
> Cart
장바구니 객체
: 장바구니에 관련한 비즈니스 로직을 처리한다
[ 기능 ]
1) 장바구니에 상품 추가
2) 장바구니에 상품 추가 시 중복 확인
3) 장바구니에서 상품을 삭제
4) 장바구니에 담긴 상품 가격 총액
/CartBean.java
package org.kosta.model;
import java.util.ArrayList;
public class CartBean {
private ArrayList<ItemDTO> itemList = new ArrayList<ItemDTO>();
public ArrayList<ItemDTO> getItemList(){
return itemList;
}
//상품 번호(itemNo)에 해당하는 상품 아이템이
// 없으면 -1 리턴
// 있으면 해당 상품 아이템 객체의 리스트에서의 인덱스를 반환
public int findIndexByNo(String itemNo) {
int index = -1;
// i = 리스트 인덱스 번호
// index = 리스트에 존재하는 상품의 위치(인덱스)
for (int i=0; i < itemList.size(); i++) {
// 리스트에 i번째(인덱스)의 itemNo가 입력받은 itemNo와 일치했을 때,
// index는 아이템의 위치를 반환해준다.
if (itemList.get(i).getItemNo().contentEquals(itemNo)) {
index = i ;
break;
}
}
return index;
}
/*
* addItem(ItemDTO) : void
* 1) 장바구니에 상품 추가
* : 2) 장바구니에 상품아이템이 중복되면 DuplicateItemException을 발생시키고,
* throw 한다.
*/
public void addItem(ItemDTO dto) throws DuplicateItemException {
//기존 리스트에 추가하려는 상품이 존재하면, (-1)
//DuplicateItemException을 발생
if (findIndexByNo(dto.getItemNo()) != -1) {
throw new DuplicateItemException();
}
//중복되지 않으면, add
itemList.add(dto);
}
/*
* removeItem(String itemNo) : void
* 3) 장바구니에서 상품을 삭제
*/
public void removeItem(String itemNo) {
//itemNo를 통해 해당 상품의 index를 받아옴
int index = findIndexByNo(itemNo);
//list에서 해당 index 객체 삭제
itemList.remove(index);
}
/*
* getTotalPrice() : void
* 4) 장바구니 담긴 상품 아이템 총액을 반환
* - 장바구니 페이지에서 접근해서 사용한다.
*/
public int getTotalPrice() {
int total = 0;
for (int i = 0; i < itemList.size(); i++) {
total += itemList.get(i).getPrice();
}
return total;
}
@Override
public String toString() {
return "CartBean [itemList=" + itemList + "]";
}
}//class
/DuplicateItemException.java
package org.kosta.model;
public class DuplicateItemException extends Exception{
//객체 직렬화를 위한 serial number id
private static final long serialVersionUID = 1L;
public DuplicateItemException() {
super("상품 아이템이 중복되어, 장바구니에 추가할 수 없습니다.");
}
}
> Item
/ItemDTO.java
package org.kosta.model;
public class ItemDTO {
private String itemNo;
private String name;
private String maker;
private int price;
private String detail;
public ItemDTO() {
super();
}
public ItemDTO(String itemNo, String name, String maker, int price, String detail) {
super();
this.itemNo = itemNo;
this.name = name;
this.maker = maker;
this.price = price;
this.detail = detail;
}
public String getItemNo() {
return itemNo;
}
public void setItemNo(String itemNo) {
this.itemNo = itemNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMaker() {
return maker;
}
public void setMaker(String maker) {
this.maker = maker;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
@Override
public String toString() {
return "ItemDTO [itemNo=" + itemNo + ", name=" + name + ", maker=" + maker + ", price=" + price + ", detail="
+ detail + "]";
}
}
/ItemDAO.java
package org.kosta.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.sql.DataSource;
public class ItemDAO {
private static ItemDAO instance=new ItemDAO();
private DataSource dataSource;
private ItemDAO() {
this.dataSource=DataSourceManager.getInstance().getDataSource();
}
public static ItemDAO getInstance() {
return instance;
}
public void closeAll(PreparedStatement pstmt,Connection con) throws SQLException {
if(pstmt!=null)
pstmt.close();
if(con!=null)
con.close();
}
public void closeAll(ResultSet rs,PreparedStatement pstmt,Connection con) throws SQLException {
if(rs!=null)
rs.close();
closeAll(pstmt, con);
}
/* 1번 기능
* getAllItemList() : ArrayList<ItemDTO>
*/
public ArrayList<ItemDTO> getAllItemList() throws SQLException{
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
ArrayList<ItemDTO> list=new ArrayList<ItemDTO>();
try {
con=dataSource.getConnection();
String sql="select item_no,name,maker from item order by item_no desc";
pstmt=con.prepareStatement(sql);
rs=pstmt.executeQuery();
while(rs.next()) {
ItemDTO dto=new ItemDTO();
dto.setItemNo(rs.getString(1));
dto.setName(rs.getString(2));
dto.setMaker(rs.getString(3));
list.add(dto);
}
}finally {
closeAll(rs, pstmt, con);
}
return list;
}
public ItemDTO findItemByNO(String itemNo) {
return null;
}
/* 2번 기능
* findItemByNo(String itemNo) : ItemDTO
*/
public ItemDTO findItemByNo(String itemNo) throws SQLException {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
ItemDTO dto = null;
try {
con = dataSource.getConnection();
String sql = "SELECT name, maker, price, detail "
+ "FROM item WHERE item_no = ?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, itemNo);
rs = pstmt.executeQuery();
if (rs.next())
dto = new ItemDTO(itemNo, rs.getString(1), rs.getString(2),
rs.getInt(3), rs.getString(4));
} finally {
closeAll(rs, pstmt, con);
}
return dto;
}
/* 3번 기능
* registerItem(ItemDTO) : void
*/
public void registerItem(ItemDTO dto) throws SQLException {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = dataSource.getConnection();
String sql = "INSERT INTO item(item_no,name,maker,price,detail) "
+ "VALUES(item_seq.nextval, ?, ?, ?, ?)";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, dto.getName());
pstmt.setString(2, dto.getMaker());
pstmt.setInt(3,dto.getPrice());
pstmt.setString(4, dto.getDetail());
pstmt.executeUpdate();
} finally {
closeAll(pstmt, con);
}
}
}//class
> Member
getCart() : 회원당 장바구니는 없거나 한개만 생성
Cart가 없으면, CartBean 객체를 생성하게 하고,
CartBean 객체가 이미 생성되어 있으면, 기존 CartBean 객체를 반환하게 한다.
/MemberDTO.java
package org.kosta.model;
public class MemberDTO {
private String id;
private String password;
private String name;
private String address;
/*
* 회원당 장바구니는 없거나 한개만 생성
*/
private CartBean cart;
/**
* getCart()를 처음 호출했을 때만, CartBean 객체를 생성하게 하고,
* CartBean 객체가 이미 생성되어 있으면, CartBean 객체를 반환하게 한다.
*/
public CartBean getCart() {
// 카트가 없을 때
if (cart == null)
// 새로운 카트 생성
cart = new CartBean();
// 카트가 있을 때는 기존 cart 리턴
return cart;
}
public MemberDTO() {
super();
}
public MemberDTO(String id, String password, String name, String address) {
super();
this.id = id;
this.password = password;
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "MemberDTO [id=" + id + ", password=" + password + ", name=" + name + ", address=" + address + ", cart="
+ cart + "]";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/MemberDAO.java
package org.kosta.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.sql.DataSource;
public class MemberDAO {
private static MemberDAO instance=new MemberDAO();
private DataSource dataSource;//DBCP
private MemberDAO() {
this.dataSource=DataSourceManager.getInstance().getDataSource();
}
public static MemberDAO getInstance() {
return instance;
}
public void closeAll(PreparedStatement pstmt,Connection con) throws SQLException {
if(pstmt!=null)
pstmt.close();
if(con!=null)
con.close();
}
public void closeAll(ResultSet rs,PreparedStatement pstmt,Connection con) throws SQLException {
if(rs!=null)
rs.close();
closeAll(pstmt, con);
}
public MemberDTO findMemberById(String id) throws SQLException {
MemberDTO vo=null;
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
con=dataSource.getConnection();
String sql="select name,address from web_member where id=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, id);
rs=pstmt.executeQuery();
if(rs.next())
vo=new MemberDTO(id,null,rs.getString(1),rs.getString(2));
}finally {
closeAll(rs, pstmt, con);
}
return vo;
}
public ArrayList<String> getAddressKind() throws SQLException{
ArrayList<String> list=new ArrayList<String>();
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
con=dataSource.getConnection();
String sql="select distinct(address) from web_member";
pstmt=con.prepareStatement(sql);
rs=pstmt.executeQuery();
while(rs.next())
list.add(rs.getString(1));
}finally {
closeAll(rs, pstmt, con);
}
return list;
}
public int getMemberTotalCount() throws SQLException {
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
int count=0;
try {
con=dataSource.getConnection();
String sql="select count(*) from web_member";
pstmt=con.prepareStatement(sql);
rs=pstmt.executeQuery();
if(rs.next())
count=rs.getInt(1);
}finally {
closeAll(rs, pstmt, con);
}
return count;
}
public ArrayList<MemberDTO> findMemberListByAddres(String address) throws SQLException{
ArrayList<MemberDTO> list=new ArrayList<MemberDTO>();
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
con=dataSource.getConnection();
String sql="select id,name from web_member where address=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, address);
rs=pstmt.executeQuery();
while(rs.next())
list.add(new MemberDTO(rs.getString(1),null,rs.getString(2),null));
}finally {
closeAll(rs, pstmt, con);
}
return list;
}
public MemberDTO login(String id,String password) throws SQLException {
MemberDTO vo=null;
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
con=dataSource.getConnection();
String sql=
"select name,address from web_member where id=? and password=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, id);
pstmt.setString(2, password);
rs=pstmt.executeQuery();
if(rs.next())
vo=new MemberDTO(id,password,rs.getString(1),rs.getString(2));
}finally {
closeAll(rs, pstmt, con);
}
return vo;
}
//회원가입
public void register(MemberDTO vo) throws SQLException {
Connection con=null;
PreparedStatement pstmt=null;
try {
con=dataSource.getConnection();
String sql="insert into web_member values(?,?,?,?)";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, vo.getId());
pstmt.setString(2, vo.getPassword());
pstmt.setString(3, vo.getName());
pstmt.setString(4, vo.getAddress());
pstmt.executeUpdate();
}finally {
closeAll(pstmt, con);
}
}
public void updateMember(MemberDTO vo) throws SQLException {
Connection con=null;
PreparedStatement pstmt=null;
try {
con=dataSource.getConnection();
String sql=
"update web_member set password=?,name=?,address=? where id=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, vo.getPassword());
pstmt.setString(2, vo.getName());
pstmt.setString(3, vo.getAddress());
pstmt.setString(4, vo.getId());
pstmt.executeUpdate();
}finally {
closeAll(pstmt, con);
}
}
}
View
[ template ]
/index.jsp
index를 실행하면 <jsp:forward> 방식으로 home.jsp로 간다
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<jsp:forward page="front">
<jsp:param value="home" name="command"/>
</jsp:forward>
/template/layout.jsp
로그인 상태일 때, header 부분에 '장바구니 보기'가 나타남
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Home</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/myhome.css" />
</head>
<body>
<div class="container">
<%-- HEARDER --%>
<div class="row header">
<div class="col-sm-12">
<h4>
<a href="${pageContext.request.contextPath}/front?command=home">
Model2 상품관리</a>
<%-- 로그인 상태일 때 장바구니 보기가 나타남 --%>
<c:if test="${sessionScope.memberDTO != null}">
<a href="${pageContext.request.contextPath}/front?command=cartview">
<img src="${pageContext.request.contextPath}/template/shoppigcart.png"
height="50"/> 장바구니
</a>
</c:if>
</h4>
</div>
</div>
<%-- MAIN --%>
<div class="row main">
<%-- main 화면 --%>
<div class="col-sm-7">
<%--
메인 화면에 대한 view 정보(url or jsp파일명)를 컨트롤러에서
동적으로 할당받는다
--%>
<c:import url="${requestScope.url}" />
</div>
<%-- 오른쪽 화면 --%>
<div class="col-sm-5">
<%-- login 상태와 login 상태가 아닐 때를 다르게 제공한다
login 아닐 시 - 로그인 폼
login 시 - [ ]님 로그인 / 로그아웃 링크
--%>
<c:choose>
<%-- login X --%>
<c:when test="${sessionScope.memberDTO == null}">
<%--login Table --%>
<form action="${pageContext.request.contextPath}/front"
method="post">
<input type="hidden" name="command" value="login">
<table>
<tr>
<td>아이디</td>
<td><input type="text" name="id" required="required"></td>
</tr>
<tr>
<td>패스워드</td>
<td><input type="password" name="password"
required="required"></td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit"
value="로그인"></td>
</tr>
</table>
</form>
<br>
<br>
</c:when>
<%-- login O --%>
<c:otherwise>
${sessionScope.memberDTO.name} 님 로그인 <br>
<a href="${pageContext.request.contextPath}/front?command=logout">로그아웃</a><br><br>
<a href="${pageContext.request.contextPath}/front?command=registerItemForm">상품등록</a>
</c:otherwise>
</c:choose>
</div>
</div>
<%-- FOOTER --%>
<div class="row footer">
<div class="col-sm-12">
경기도 성남시 분당구 삼평동 대왕판교로 670길 유스페이스2 B동 8층 TEL. 031-606-9311~20 <br>
Copyright © 2020 KOSTA ALL RIGHTS RESERVED
</div>
</div>
</div>
</body>
</html>
[ CSS ]
/myhome.css
@charset "UTF-8";
.header{
text-align: center;
height: 70px;
padding: 15px;
}
.main{
text-align: center;
height: 400px;
}
.footer{
text-align: center;
height: 10px
}
th{
text-align: center;
}
.detailTable{
text-align: letf;
}
-- 기능 1 : 장바구니 담기
로그인 상태일 때 '장바구니 담기' 기능 추가됨
+ '장바구니 담기' 를 button처리하여 onclick시 , javascript에서 함수가 작동하게 한다.
함수는 confirm처리하여
- '확인'누르면(true) -> 담기 -> 서버로 전송 (command:addcart가 전송되어 AddCartController가 실행됨)
*addcart-result.jsp로 가는 것이 목적!
- '취소'누르면(false) -> return으로 동작하게 한다.
/item/item-detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<script type="text/javascript">
function addCartBtn(){
if (confirm("쇼핑카트에 담으시겠습니까?")){ //확인
//javascript form submit
document.getElementById("addCartForm").submit();
//command:addcart가 전송되어 AddCartController가 실행됨
} else { //취소
return;
}
}
</script>
<c:set var="itemDTO" value="${requestScope.itemDTO}"></c:set>
<h3> ${itemDTO.name}의 Item Detail </h3><br><br>
<table class="table table-hover table-bordered detailTable">
<tr>
<td>NO</td>
<td>${itemDTO.itemNo}</td>
</tr>
<tr>
<td>Name</td>
<td>${itemDTO.name}</td>
</tr>
<tr>
<td>Maker</td>
<td>${itemDTO.maker}</td>
</tr>
<tr>
<td>Price</td>
<td>${itemDTO.price}</td>
</tr>
<tr>
<td>Detail</td>
<%-- pre tag --%>
<td><pre>${itemDTO.detail}</pre></td>
</tr>
<%-- 로그인 상태일 떄 '장바구니 담기' 기능 추가됨 --%>
<c:if test="${sessionScope.memberDTO != null}">
<tr>
<td colspan="2" align="center">
<form action="front" method="post" id="addCartForm">
<input type="hidden" name="command" value="addcart">
<%-- AddCartController에 보내줄 itemNo --%>
<input type="hidden" name="itemNo" value="${requestScope.itemDTO.itemNo}">
<input type="button" onclick="addCartBtn()" value="장바구니 담기">
</form>
</td>
</tr>
</c:if>
</table>
(장바구니에 상품 추가 후, 장바구니로 이동 여부 묻기)
/item/addcart-result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript">
//확인 누르면
if (confirm("장바구니에 추가되었습니다!\n장바구니로 이동하시겠습니까?")) {
location.href = "${pageContext.request.contextPath}/front?command=cartview"
} else { // 취소 누르면
location.href = "${pageContext.request.contextPath}/front?command=home"
}
</script>
기능 2 : 장바구니 보기
1) item-detail.jsp에서 '장바구니 담기'후 '장바구니로 이동' 했을 경우
2) 시작 화면에서 상단에 '장바구니 보기' 클릭했을 경우
-- > 둘다 'handlerMapping 에서 command=cartview 를 통해 이동된다.
/item/cart.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript">
function deleteItemBtn() {
if(confirm("장바구니에서 해당 상품을 삭제하시겠습니까?")){
//javascript form submit
document.getElementById("deleteItemForm").submit();
//command(deleteCart)와 itemNo(${item.itemNo})이 front로 제출된다.
} else {
return;
}
}
</script>
<c:choose>
<c:when test="${empty sessionScope.memberDTO.cart.itemList}">
장바구니에 담긴 상품이 없습니다.
</c:when>
<c:otherwise>
<table class = "table table-hover table-bordered">
<caption> <h3> 장바구니 </h3> </caption>
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>제조사</th>
<th>가격</th>
<th></th>
</tr>
</thead>
<tbody>
<c:forEach items="${sessionScope.memberDTO.cart.itemList}" var="item">
<tr>
<td>${item.itemNo}</td>
<td>${item.name}</td>
<td>${item.maker}</td>
<td>${item.price}</td>
<td>
<form action="front" method="POST" id="deleteItemForm">
<input type="hidden" name="command" value="deleteCart">
<input type="hidden" name="itemNo" value="${item.itemNo}">
<input type="button" onclick="deleteItemBtn()" value="삭제">
</form>
</td>
</tr>
</c:forEach>
<%-- 총 금액
: session에서 dto를 가져와서, 그 안에서 cart를 가져와서,
CartBean에 있는 totalPrice method를 이용
--%>
<tr>
<td colspan="5" align="center">
총 금액 : ${sessionScope.memberDTO.cart.totalPrice}
</td>
</tr>
</tbody>
</table>
</c:otherwise>
</c:choose>
기능 3 : 장바구니에 담을 상품 중복 여부 체크
/item/duplicate_cart.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript">
alert("이미 장바구니에 존재하는 물품입니다!");
location.href = "${pageContext.request.contextPath}/front?command=home";
</script>
Controller
/Controller.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Controller {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
/ HandlerMapping.java
package org.kosta.controller;
public class HandlerMapping {
private static HandlerMapping instance=new HandlerMapping();
private HandlerMapping() {}
public static HandlerMapping getInstance() {
return instance;
}
public Controller create(String command) {
Controller controller=null;
if(command.contentEquals("home")) {
controller=new HomeController();
}
else if(command.contentEquals("ItemDetail")) {
controller=new ItemDetailController();
}
else if(command.contentEquals("login")) {
controller=new LoginController();
}
else if(command.contentEquals("logout")) {
controller=new LogoutController();
}
else if(command.contentEquals("registerItemForm")) {
controller=new RegisterItemFormController();
}
else if(command.contentEquals("RegisterItem")) {
controller=new RegisterItemController();
}
else if(command.contentEquals("RegisterItemResult")) {
controller=new RegisterItemResultController();
}
// 장바구니 담기 기능
else if(command.contentEquals("addcart")) {
controller=new AddCartController();
}
// 장바구니 보기 기능
else if(command.contentEquals("cartview")) {
controller=new CartViewController();
}
// 장바구니에 있는 상품 삭제 기능
else if(command.contentEquals("deleteCart")) {
controller=new deleteItemController();
}
return controller;
}
}
/DispatcherServlet.java
handleRequest method 작동 방식
1. 에러(예외) 발생 시, 콘솔에 메세지 발생 경로 출력 후, error.jsp로 redirect 방식으로 view로 이동한다.
2. 클라이언트가 전송한 command 정보를 받는다.
3. HandlerMapping 을 이용해 개별 컨트롤러 객체를 컨트롤러 인터페이스 타입으로 반환받는다.
4. 개별 컨트롤러를 실행한다.
5. 실행 후 반환된 String url 정보를 이용해,
forward 방식 or redirect 방식으로 view로 이동해 응답하게 한다.
package org.kosta.controller;
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;
@WebServlet("/front")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.handleRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
this.handleRequest(request, response);
}
protected void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String command=request.getParameter("command");
Controller controller=HandlerMapping.getInstance().create(command);
String url=controller.execute(request, response);
if(url.startsWith("redirect:"))
response.sendRedirect(url.substring(9));
else
request.getRequestDispatcher(url).forward(request, response);
}catch (Exception e) {
e.printStackTrace(); // 예외 메세지와 발생 경로를 모두 콘솔에 출력한다
response.sendRedirect("error.jsp");
}
}
}
--- 기능 1 : 장바구니 담기 Controller
addcart-result.jsp로 가는 것이 목적!
< 할 일 >
1. 로그인 체크 : 세션이 존재하고 + 세션 내의 인증 정보가 존재하는지 확인
(로그인이 안 되어있은 경우 : "redirect:front?command=home" 로 이동한다.)
2. 인증정보 (회원객체)가 존재하면 로그인 한것이므로, 상품을 담기 위해 장바구니 객체를 생성한다.
(만약, 기존 장바구니가 있으면 기존 장바구니를 이용한다.)
3. 장바구니 객체에 아이템 상품 정보를 추가한다.
4. 상품아이템을 추가한 후 addcart_result.jsp로 이동한다.
5. 예외) 장바구니에 동일한 상품 아이템이 있을 경우에는 추가하지 않고, duplicate-cart.jsp로 이동한다.
/AddCartController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.kosta.model.DuplicateItemException;
import org.kosta.model.ItemDAO;
import org.kosta.model.ItemDTO;
import org.kosta.model.MemberDTO;
public class AddCartController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
//url의 default값은 home
String url = "redirect:/front?command=home";
// 로그인 여부 확인
HttpSession session = request.getSession(false);
// 1. 세션 유무 확인
if (session != null) {
MemberDTO memberDTO
= (MemberDTO) session.getAttribute("memberDTO");
// 2. 세션에 할당된 값 유무 확인
if (memberDTO != null) {
//item-detail.jsp에서 itemNo 가져오기
String itemNo = request.getParameter("itemNo");
//itemNo를 통해 itemDTO 객체 만들기
ItemDTO itemDTO = ItemDAO.getInstance().findItemByNo(itemNo);
//로그인되어있는 것 확인 후,
// 1. 카트 생성 (getCart)
// 2. 아이템 추가(addItem) : 중복여부 체크함
try { // 중복이 아닐 경우
memberDTO.getCart().addItem(itemDTO);
url = "/item/addcart-result.jsp";
} catch (DuplicateItemException de) { // 중복일 경우
url = "/item/duplicate_cart.jsp";
}
}
}
return url;
}
}
--- 기능 2 : 장바구니 보기 Controller
/CartViewController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CartViewController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
request.setAttribute("url", "/item/cart.jsp");
return "/template/layout.jsp";
}
}
--- 기능 4 : 장바구니에 있는 상품 삭제 기능 Controller
/deleteItemController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.kosta.model.MemberDTO;
public class deleteItemController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
//비 로그인 상태이면 home으로 보낸다.
//(session이 종료되었을 경우)
String url = "front?command=home";
// 로그인 여부 확인
HttpSession session = request.getSession(false);
// 로그인 상태이면, 아이템 삭제 후, url을 바꿔준다.
if (session != null && session.getAttribute("memberDTO") != null) {
// dto : 로그인 정보
MemberDTO dto
= (MemberDTO) session.getAttribute("memberDTO");
// itemNo : cart.jsp에서 보낸 itemNo
String itemNo = request.getParameter("itemNo");
//dto에서 CartBean을 얻어와서, 그 안에있는 removeItem을 이용해
//itemList에 있는 dto를 삭제한다.
dto.getCart().removeItem(itemNo);
// 다시 장바구니로 보내준다.
url = "redirect:front?command=cartview";
}
return url;
}
}
[ 브라우저 화면 ]
> Home (index.jsp -> layout.jsp)
> 1-1. 로그인 상태에서, 장바구니에 상품 담기 (확인)
> 4. 중복된 상품일 경우, (duplicate_cart.jsp)
> 1-3. 장바구니 추가 완료 / 장바구니 이동 여부 묻기
> 2-1. '확인' 누르고, 장바구니로 이동 / home에서 '장바구니 링크'클릭 후, 장바구니 보기
> 3-1. '삭제' 버튼 클릭 (삭제여부 물으면 '확인' 클릭)
> 3-2. 삭제된 후 다시 장바구니 리스트 화면으로 돌아옴