변수 설정
디폴트 생성자
상품 정보를 모두 받는 생성자 설정

이 외 Setter & Getter, toString, hashCode(),
객체가 동일한 인스턴스인지 확인하는 equals 메서드
새로운 객체를 형성하고, 현재 객체의 속성값을 사용해 초기화 하는 clone메서드 구현
package org.comstudy.day06.shop;
import java.util.ArrayList;
import java.util.List;
public class ProductDAOImpl implements ProductDAO {
private static final List<ProductDTO> productList;
private static int seq;
static {
productList = new ArrayList<ProductDTO>(); // productList 초기화
productList.add(new ProductDTO(1, "냉장고", 300, "삼성", 0));
productList.add(new ProductDTO(2, "세탁기", 100, "LG", 0));
productList.add(new ProductDTO(3, "선풍기", 30, "삼성", 0));
productList.add(new ProductDTO(4, "컴퓨터", 160, "ASUS", 0));
productList.add(new ProductDTO(5, "테레비", 200, "LG", 0));
productList.add(new ProductDTO(6, "에어컨", 250, "케리어", 0));
seq = 7;
}
// CRUD (입력, 출력, 검색, 수정, 삭제)
@Override
public void insert(ProductDTO dto) { // 상품 번호 설정 및 상품 목록에 추가
dto.setSeq(seq++);
productList.add(dto);
}
@Override
public List<ProductDTO> selectAll() { // 모든 상품 조회
return productList;
}
private int findIndex(int seq) { // 상품 번호 인덱스 반환
int idx = -1;
for(int i=0; i<productList.size(); i++) {
if(productList.get(i).getSeq() == seq) {
idx = i;
break;
}
}
return idx;
}
@Override
public ProductDTO findBySeq(int seq) { // 상품 번호로 상품 조회
ProductDTO product = null;
int i = findIndex(seq);
if(i != -1) {
product = productList.get(i);
}
return product;
}
@Override
public void update(ProductDTO dto) { // 상품 정보 수정
int i = findIndex(dto.getSeq()); // 인덱스 번호 찾아서
if(i != -1) {
productList.set(i, dto); // 수정
}
}
@Override
public void delete(ProductDTO dto) { // 상품 삭제
int i = findIndex(dto.getSeq());
if(i != -1) {
productList.remove(i);
}
}
}
package org.comstudy.day06.shop;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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 javax.servlet.http.HttpSession;
@WebServlet("/shop/*")
public class ShopController extends HttpServlet {
private String viewName = "";
private String prefix = "/WEB-INF/views/"; // JSP 파일의 경로를 저장
private String suffix = ".jsp"; // JSP 파일의 확장자 저장
ProductDAO dao = new ProductDAOImpl(); // DAO 객체 생성
// 리다이렉트 또는 포워딩 결정 메서드
protected void dispatcher(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(viewName.indexOf("redirect:") == 0) { // 뷰 이름에 "redirect:"가 포함되어 있으면 Redirect
response.sendRedirect(viewName.substring("redirect:".length()));
} else {
String path = prefix + viewName + suffix; //JSP 파일의 경로 생성
RequestDispatcher view = request.getRequestDispatcher(path); // RequestDispatcher 객체 생성
view.forward(request, response); // 포워딩
}
}
// process : doGet()과 doPost() 통합 처리하는 메서드
protected void process(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=UTF-8");
// urlPattern 만들기
String reqUri = req.getRequestURI();
String ctxPath = req.getContextPath();
int beginIndex = ctxPath.length();
String urlPattern = reqUri.substring(beginIndex);
System.out.println("Url Pattern : " + urlPattern);
// <POST 방식>
if("POST".equals(req.getMethod() ) ) {
// 상품 등록, 수정, 삭제 등의 기능
//<Get 방식>
} else {
if("/shop/list.do".equals(urlPattern)) {
List<ProductDTO> pList = (List<ProductDTO>)dao.selectAll(); // 모든 상품 목록 가져옴
req.setAttribute("pList", pList); // 요청 객체에 상품 목록 속성 설정
viewName = "shop/productList";
} else if("/shop/cart.do".equals(urlPattern)) {
// 상품 seq, 수량을 파라미터로 전달 받고
// 목록에서 seq를 찾아서 해당 상품의 객체를 장바구니 목록에 저장
// 장바구니 목록은 session에 바인딩 하고 장바구니 목록 뷰 보여줌
viewName = "shop/cartList";
} else if("/shop/detail.do".equals(urlPattern)) {
int seq = Integer.parseInt(req.getParameter("seq")); // 상품 번호 파라미터 추출
ProductDTO product = dao.findBySeq(seq); // 상품 번호에 해당하는 상품 정보 가져옴
req.setAttribute("product", product); // 요청 객체에 상품 정보 속성 설정
viewName = "shop/productDetail";
} else if ("/shop/cart_add.do".equals(urlPattern)) {
// 요청 파라미터로부터 상품 번호와 수량을 가져옴
int seq = Integer.parseInt(req.getParameter("seq")); // 상품 번호 파라미터 추출
int ea = Integer.parseInt(req.getParameter("ea")); // 수량 파라미터 추출
// 요청된 상품 번호에 해당하는 상품 조회
ProductDTO product = dao.findBySeq(seq);
ProductDTO newProduct = (ProductDTO) product.clone(); // 상품 정보 복제해서 newPoduct에 넣기
newProduct.setEa(ea); // 상품 수량 설정
// 세션에서 장바구니 목록을 가져옴.
HttpSession session = req.getSession(); // 현재 요청의 세션 객체 가져옴
List<ProductDTO> cart = (List<ProductDTO>) session.getAttribute("cart"); // 세션에서 장바구니 목록 가져옴
if (cart == null) {
cart = new ArrayList<>(); // 장바구니가 비어있는 경우 새로운 장바구니 목록 생성
}
// 장바구니에 이미 동일한 상품이 존재하는지 확인
// 동일 상품이 있으면 수량을 증가
// 동일 상품 없으면 새로운 상품 추가
boolean samething = false;
for (ProductDTO item : cart) { // 장바구니 목록 순회
if (item.getSeq() == newProduct.getSeq()) { // 같은 상품이 있을때
item.setEa(item.getEa() + newProduct.getEa()); // 더함
samething = true; // 같은 상품 있음
break;
}
}
if (!samething) { // 같은 상품 없을 때
cart.add(newProduct);
}
// 장바구니 목록을 세션에 다시 저장
session.setAttribute("cart", cart);
// 장바구니 페이지로 리다이렉트
viewName = "redirect:cart.do";
} else if("/shop/cart_remove.do".equals(urlPattern)) {
int seq = Integer.parseInt(req.getParameter("seq"));
HttpSession session = req.getSession();
List<ProductDTO> cart = (List<ProductDTO>)session.getAttribute("cart"); // 세션 안에 있는지 확인
if(cart != null) {
//seq가 일치하는 index를 cartList에서 찾아서 제거
int index = cart.indexOf(new ProductDTO(seq));
if(index != -1) {
cart.remove(index);
}
}
viewName = "redirect:cart.do";
}
}
dispatcher(req, resp); // 포워딩
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
process(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
process(req, resp);
}
}





<%@ 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>
</head>
<body>
<h1> 상품 상세보기 </h1>
<table width="500" border="1">
<tr>
<th>번호</th><td>${product.seq}</td>
</tr>
<tr>
<th>상품명</th><td>${product.title}</td>
</tr>
<tr>
<th>가격</th><td>${product.price}</td>
</tr>
<tr>
<th>메이커</th><td>${product.maker}</td>
</tr>
<tr>
<th>수량</th>
<td>
<select id="ea">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</td>
</tr>
</table>
<script>
function addCartFn(element){
var seq = element.dataset.seq;
var ea = document.getElementById("ea").value;
var url = "cart_add.do?seq=" + seq + "&ea=" + ea;
console.log(url);
window.location.href = url;
}
</script>
<a href="list.do">상품 목록</a>
<a href="cart.do">장바구니 목록</a>
<button data-seq="${product.seq}" onclick="addCartFn(this)">장바구니에 추가</button>
</body>
</html>

jstl 사용하기
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 를 통해 사용선언
- JSP 파일에서 JSTL 태그 사용 가능하게 됨
- ${}을 사용하여 데이터를 효율적으로 표현 가능
- <c:if>, <c:forEach> 등을 사용해 조건부나 반복문 생성 가능함
- {empty}는 JSTL EL에서 사용되는 표현식 중 하나,
test={empty}를 통해 비어 있으면 true를 반환하고, 비어있지 않으면 false를 반환
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@page import="org.comstudy.day06.shop.ProductDTO"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>장바구니 목록</title>
<script>
function removeCartFn(btn) {
var seq = btn.dataset.seq;
var url = "cart_remove.do?seq=" + seq;
location.href = url;
}
</script>
</head>
<body>
<%
int eaTotal = 0;
int priceTotal = 0;
%>
<h1>장바구니 목록</h1>
<c:if test="${empty cart}">
<p>장바구니에 상품이 없습니다.</p>
</c:if>
<c:if test="${not empty cart}">
<table border="1" width="500">
<thead>
<tr>
<th>상품 번호</th>
<th>상품명</th>
<th>메이커</th>
<th>수량</th>
<th>가격</th>
<th>삭제</th>
</tr>
</thead>
<tbody>
<c:forEach var="item" items="${cart}">
<%
ProductDTO item = (ProductDTO) pageContext.findAttribute("item");
if (item != null) {
eaTotal += item.getEa();
priceTotal += item.getPrice() * item.getEa();
%>
<tr>
<td>${item.seq}</td>
<td>${item.title}</td>
<td>${item.maker}</td>
<td>${item.ea}</td>
<td>${item.price * item.ea}</td>
<td><button data-seq="${item.seq}" onclick="removeCartFn(this)">장바구니에서 제거</button></td>
</tr>
<%
}
%>
</c:forEach>
</tbody>
<tfoot>
<tr>
<th colspan="3">합 계</th>
<td><%=eaTotal %></td>
<td><%=priceTotal %></td>
<td><button>구매하기</button></td>
</tr>
</tfoot>
</table>
</c:if>
<a href="list.do">상품 목록으로 돌아가기</a>
</body>
</html>