일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 스프링
- 대분류/중분류/소분류
- ajax
- 고객센터 구현
- 로그인과 장바구니 구현
- 교보문고 따라하기
- json
- 프로그래머스
- Level 1
- Spring MVC
- SESSION
- 이메일로 인증코드 전송 구현
- 일단_해보는거야
- 오라클
- jsp 프로젝트
- java
- 코딩
- Sts
- 인증코드로 비밀번호 변경 구현
- Oracle
- js
- MVC
- 자바
- jsp
- jquery
- MySQL
- jakarta.mail
- 다중 카테고리 구현
- 세션
- Spring
감 잃지말고 개발하기
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #7. 장바구니 수량 변경하기 (2탄) 본문
지난 포스팅에서는 장바구니 수량을 변경하는 로직의 전체적인 흐름을 살펴본 후, 클라이언트 딴의 로직을 정리해 보았다.
이번 포스팅에서는 클라이언트 딴을 이어 서버 딴에서의 로직을 정리해 보도록 하겠다.
♠ 해당 구현의 로직 흐름이 궁금하면 아래 포스팅을 참고하세요 ♠
2023.05.24 - [JSP/MVC] - [JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #6. 장바구니 수량 변경하기 (1탄)
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #6. 장바구니 수량 변경하기 (1탄)
세션 및 로그인 도서 장바구니 구현 여섯 번째 포스팅이다. 저번 포스팅을 끝으로 기본적인 장바구니 구현이 완성되었다. 이제 추가적인 구현으로, 장바구니 페이지에서 도서의 수량을 변경하
persimmon-ary-stepbystep.tistory.com
목표
♠ JSP 서버 딴에서 MVC 패턴을 지키면서 AJAX방식을 처리할 수 있다.
서버 딴 로직 코드 및 실행화면
1. 컨트롤러(AjaxFrontController.java)
AJAX 방식을 처리하는 컨트롤러에서 클라이언트에서 요청하는 URL에 대한 매핑을 처리한다.
/bookCartFormQty.ax로 요청되면 BookCartFormQtyAction 클래스를 호출한다.
package controller;
import java.io.IOException;
import java.rmi.ServerException;
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 action.AjaxAction;
import action.BookCartFormQtyAction;
/** AJAX로 데이터 통신 */
@WebServlet("*.ax")
public class AjaxFrontController extends HttpServlet {
protected void doProcess(HttpServletRequest req, HttpServletResponse resp)
throws ServerException, IOException, ServletException {
req.setCharacterEncoding("UTF-8");
/* 1. 요청 주소 파악 */
String requestURI = req.getRequestURI();
String contextPath = req.getContextPath();
String command = requestURI.substring(contextPath.length());
/* 2. 각 요청 주소의 매핑 처리 */
AjaxAction action = null;
// 장바구니 수량 증가/감소 요청
if (command.equals("/bookCartFormQty.ax")) {
action = new BookCartFormQtyAction();
try {
action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServerException, IOException, ServletException {
doProcess(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServerException, IOException, ServletException {
doProcess(req, resp);
}
}
2. Action 클래스(BookCartFormQtyAction.java)
☞ Action 클래스 처리 흐름
- 세션 확인
- 로그인의 경우, DB의 장바구니 테이블에서 해당 도서 수량 +1 / -1
- 비로그인의 경우, 세션의 장바구니 속성에서 해당 도서 수량 +1 / -1
- 처리 결과를 브라우저에 응답
- 응답할 결과 형태는 int형 타입으로 할 것이다.
- DB 처리에 성공할 경우 1
- DB 처리에 실패한 경우 -2
- 세션 장바구니 속성을 처리한 경우 0
- 세션이 존재하지 않는 경우 -1을 브라우저에 건네줄 것이다.
- 이에 따라 HttpServletResponse 객체에 컨텐츠 유형을 "text/plain"으로 설정한다.
- 응답할 결과 형태는 int형 타입으로 할 것이다.
☞ SessionUtil.isLogined(req, resp);
해당 클래스의 isLogined() 메서드는 세션의 로그인 상태를 확인하는 메서드이다.
로그인된 상태면 1을, 비로그인 상태면 0을, 세션이 존재하지 않는다면 -1을 리턴한다.
♠ SessionUtil 클래스 꼬라지는 아래 포스팅을 참고하세요(공통 클래스 참고) ♠
2023.05.20 - [JSP/MVC] - [JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #2. DB 테이블 및 공통 클래스 설정
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #2. DB 테이블 및 공통 클래스 설정
세션 및 로그인 도서 장바구니 구현 두 번째 포스팅이다. 저번 포스팅에서는 교보문고 페이지를 살펴보면서 구현 방향을 정리해 보았다. 이번 포스팅에서는 본격적인 로직 구현에 앞서 이번 과
persimmon-ary-stepbystep.tistory.com
☞ service.upCartQty(b_id, (String) req.getSession().getAttribute("userId"));
service 객체의 upCartQty 메서드에 첫 번째 인자로 도서 아이디를, 두 번째 인자로 세션의 로그인 유저 아이디를 건네준다.
☞ handleDBResult(dbResult);
해당 메서드는 DB 처리 결과에 따른 리턴값을 고정시키기 위해 만든 메서드이다.
파라미터 dbResult에는 1 또는 -1의 값이 저장되는데(아래의 Service 클래스 참고),
값이 1인 경우에는 1을, -1인 경우에는 -2를 리턴한다.
☞ updateCartQuantity(ArrayList<Cart> cartList, int b_id, int quantityChange);
해당 메서드는 세션의 장바구니 속성 도서 수량을 처리하는 메서드이다.
인자 quantityChange가 1인 경우에는 수량을 1 증가시키고,
-1인 경우에는 현재 해당 도서의 수량이 1보다 큰 경우에만 수량을 -1 감소하도록 처리한 후 장바구니를 리턴한다.
package action;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import svc.BookCartFormQtyService;
import util.SessionUtil;
import vo.Cart;
/** 장바구니 도서의 수량을 1 증가/감소하는 요청을 처리하는 Action 클래스 */
public class BookCartFormQtyAction implements AjaxAction {
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
/* 요청 URL에서 전달된 파라미터 값 저장 */
int b_id = Integer.parseInt(req.getParameter("b_id"));
String how = req.getParameter("how");
int returnResult = -1;
switch (SessionUtil.isLogined(req, resp)) {
case 1:
// 로그인
// DB 처리
BookCartFormQtyService service = new BookCartFormQtyService();
int dbResult = 0;
if(how.equals("up")) {
// 장바구니 수량 +1
dbResult = service.upCartQty(b_id, (String) req.getSession().getAttribute("userId"));
} else {
// 장바구니 수량 -1
dbResult = service.downCartQty(b_id, (String) req.getSession().getAttribute("userId"));
}
returnResult = handleDBResult(dbResult);
break;
case 0:
// 비로그인
ArrayList<Cart> cartList = (ArrayList<Cart>) req.getSession().getAttribute("cartList");
if (how.equals("up")) {
cartList = updateCartQuantity(cartList, b_id, 1);
} else if (how.equals("down")) {
cartList = updateCartQuantity(cartList, b_id, -1);
}
// 확인용
System.out.println("수정된 장바구니 ------");
for(Cart cart:cartList) {
System.out.println(cart.toString());
}
returnResult = 0;
break;
default:
break;
}
/* 결과 응답 처리
* 응답할 결과 형태 : int형 데이터 -> dataType: 'TEXT'
* resp.setContentType("text/plain"); 응답의 컨텐츠 유형을 설정
* */
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.print(returnResult);
}
/** DB 결과 처리 */
private int handleDBResult(int dbResult) {
if(dbResult == 1) {
// DB에 성공적으로 저장된 경우
return 1;
} else {
// DB에 저장 X (DB 에러)
return -2;
}
}
/** 세션 장바구니 속성 처리
* @return */
private ArrayList<Cart> updateCartQuantity(ArrayList<Cart> cartList, int b_id, int quantityChange) {
for (Cart cart : cartList) {
if (cart.getC_b_id() == b_id) {
switch (quantityChange) {
case 1:
// 수량 증가
cart.setC_b_qty(cart.getC_b_qty() + quantityChange);
break;
default:
// 수량 감소
// 수량이 1 보다 크고 감소하는 경우에만 처리되도록 설정
if(cart.getC_b_qty() > 1) cart.setC_b_qty(cart.getC_b_qty() + quantityChange);
break;
}
}
}
return cartList;
}
}
3. Service 클래스(BookCartFormQtyService.java)
☞ upCartQty(int b_id, String m_id);
해당 메서드는 DB cart 테이블에서 도서 아이디와 로그인 아이디에 따른 도서 항목의 수량을 1 증가시킨다.
DB 처리에 성공하면 1을, 실패하면 -1을 리턴한다.
☞ downCartQty(int b_id, String m_id)
해당 메서드는 DB cart 테이블에서 도서 아이디와 로그인 아이디에 따른 도서 항목의 수량을 1 감소시킨다.
마찬가지로 DB 처리에 성공하면 1을, 실패하면 -1을 리턴한다.
package svc;
import java.sql.Connection;
import java.sql.SQLException;
import dao.CartDAO;
import db.JdbcUtil;
/** 장바구니 항목 수량 증가 요청을 처리하는 비즈니스 로직을 구현하는 Service 클래스 */
public class BookCartFormQtyService {
/** 장바구니 항목의 수량을 증가시키는 메서드
* @throws SQLException */
public int upCartQty(int b_id, String m_id) throws SQLException {
/* DB 작업 */
Connection conn = JdbcUtil.getConnection();
CartDAO cartDAO = CartDAO.getInstance();
cartDAO.setConnection(conn);
int updateCount = cartDAO.updateQty(b_id, m_id, "up");
int isUpdateSuccess = -1;
if((updateCount) > 0) {
conn.commit();
isUpdateSuccess = 1;
}
else conn.rollback();
conn.close();
return isUpdateSuccess;
}
/** 장바구니 항목 수량을 -1하는 메서드
* @throws SQLException */
public int downCartQty(int b_id, String m_id) throws SQLException {
/* DB 작업 */
Connection conn = JdbcUtil.getConnection();
CartDAO cartDAO = CartDAO.getInstance();
cartDAO.setConnection(conn);
int isUpdateSuccess = -1;
int updateCount = cartDAO.updateQty(b_id, m_id, "down");
if((updateCount) > 0) {
// DB 수정 성공
conn.commit();
isUpdateSuccess = 1;
}
else conn.rollback();
conn.close();
return isUpdateSuccess;
}
}
4. DAO 클래스(CartDAO.java)
기존 CartDAO 클래스에 아래 메서드를 추가해 준다.
인자 status의 값이 "up" 이면 증가시키는 쿼리문을, "down"이면 감소시키는 쿼리문을 sql 변수에 저장한다.
/** 도서 수량을 1 증가시키는 메서드
* @param status */
public int updateQty(int b_id, String m_id, String status) {
PreparedStatement pstmt = null;
int updateCount = 0;
String sql = "";
if(status.equals("up")) {
sql = "UPDATE jspbookshop.cart "
+ "SET ca_b_qty = ca_b_qty + 1 "
+ "WHERE ca_b_id = ? "
+ "AND ca_m_id = ?";
} else {
sql = "UPDATE jspbookshop.cart "
+ "SET ca_b_qty = ca_b_qty - 1 "
+ "WHERE ca_b_id = ? "
+ "AND ca_m_id = ?";
}
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, b_id);
pstmt.setString(2, m_id);
updateCount = pstmt.executeUpdate();
} catch (Exception e) {
System.out.println(" Ca.DAO : updateQty() ERROR : "+e);
} finally {
close(pstmt);
}
return updateCount;
}
5. 브라우저 결과
AJAX에 대한 처리가 정상적으로 수행되면, ajax 함수의 success에서 응답 결과에 따른 처리를 수행한다.
경우 1. 비로그인 상태
1. ▼ 수량 증가
<장하준의 경제학 레시피> 도서의 수량을 1 증가시켜 보았다.
수량이 2로 변하고, 금액이 바뀌었으며, 최종 총액 또한 알맞게 변경되었음이 확인된다.
▼ 콘솔 출력 확인
변경하고자 하는 도서의 아이디 및 가격, 현재 수량, 총액 정보가 잘 출력되었다.
▼ 서버 딴 출력 확인
서버 딴에서 세션의 장바구니 속성의 도서 정보가 제대로 변경되었다.
2. ▼ 수량 증가
다시 <장하준의 경제학 레시피> 도서의 수량을 1 감소시켜 보았다.
▼ 콘솔 출력 확인
마찬가지로 잘 출력되었다.
▼ 서버 딴 출력 확인
서버 딴 역시 마찬가지로 세션의 장바구니 속성의 도서 정보가 제대로 변경되었다.
경우 2. 로그인 상태
1. ▼ 기존 장바구니 확인
먼저 사용자 yejii의 장바구니를 확인해 보자.
여기서 <스즈메의 문단속> 도서 수량을 변경해 볼 것이다. 현재 <스즈메의 문단속> 도서 수량은 3이다.
2. ▼ 수량 감소
<스즈메의 문단속> 도서 수량이 2로 변경되었고 금액 역시 변경되었다.
▼ 콘솔 출력 확인
▼ DB 확인
실제로 값이 변경되었는지 DB에 확인해 보니 잘 변경되어 저장되었음을 확인할 수 있다.
이렇게 세션의 로그인 속성과 장바구니 속성 및 DB를 이용해 장바구니 수량을 변경하는 로직이 모두 구현되었다.
장바구니 수량 변경 구현 끝.
'JSP > MVC' 카테고리의 다른 글
[JSP][MVC][MySQL] Select 박스 옵션에 따른 페이징 처리 구현하기 #3. 로직 구현(마지막) (0) | 2023.05.27 |
---|---|
[JSP][MVC][MySQL] Select 박스 옵션에 따른 페이징 처리 구현하기 #2. 로직 구현 (0) | 2023.05.27 |
[JSP][MVC][MySQL] Select 박스 옵션에 따른 페이징 처리 구현하기 #1. 기본 설정 (0) | 2023.05.27 |
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #6. 장바구니 수량 변경하기 (1탄) (0) | 2023.05.24 |
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #2. DB 테이블 및 공통 클래스 설정 (1) | 2023.05.20 |
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #1. 구현 방향 설정 (0) | 2023.05.19 |