일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 로그인과 장바구니 구현
- json
- 세션
- Sts
- 인증코드로 비밀번호 변경 구현
- 고객센터 구현
- 자바
- MVC
- Spring MVC
- 일단_해보는거야
- Spring
- 코딩
- 프로그래머스
- 대분류/중분류/소분류
- ajax
- jsp
- 다중 카테고리 구현
- 오라클
- Oracle
- jakarta.mail
- SESSION
- 이메일로 인증코드 전송 구현
- 교보문고 따라하기
- MySQL
- Level 1
- 스프링
- jsp 프로젝트
- jquery
- js
- java
감 잃지말고 개발하기
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #4. 장바구니 주문 구현하기(마지막) 본문
세션을 이용해 사용자가 원하는 도서를 장바구니에 추가하고 이를 출력해 보며,
이와 더해 사용자가 입력한 배송지 정보를 쿠키로 생성해 출력하는 로직 기록하고자 한다.
저번 포스팅에서는 세션에 저장된 장바구니를 화면에 출력하는 장바구니 페이지와 주문 페이지를 구현해 보았다.
이번 포스팅에서는 주문 페이지에서 사용자가 배송지 정보를 입력하면 주문한 장바구니 목록과 배송지 정보를 출력하는 주문 확인 페이지를 구현해 보도록 하겠다.
배송지 정보를 저장하기 위해 쿠키를 쓸 건데 앞에서 말했듯이 개인정보를 쿠키에 담는 건 좋지 않지만, 복습 겸 해볼 것이다.
♠ 프로젝트 전체 로직 흐름이 궁금하면 아래 포스팅을 참고하세요 ♠
2023.05.15 - [JSP/MVC] - [JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #1. 구현 흐름 정리하기
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #1. 구현 흐름 정리하기
세션을 이용해 사용자가 원하는 도서를 장바구니에 추가하고 이를 출력해 보며, 이와 더해 사용자가 입력한 배송지 정보를 쿠키로 생성해 출력하는 로직 기록하고자 한다. 개인 정보가 포함되
persimmon-ary-stepbystep.tistory.com
목표
♠ 세션과 쿠키를 사용할 수 있다.
로직 흐름
- 주문 페이지에서 배송지를 입력하고 결제하기 버튼을 누른다(bookShippingCheckOut.ok).
- 해당 컨트롤러에서 해당 URL을 매핑해 필요한 Action 클래스를 호출한다(BookFrontController.java).
- Action 클래스에서
- 세션을 확인한 후 세션에 저장된 장바구니 속성을 가져온다.
- 주문 페이지에서 전송된 배송지 정보를 쿠키로 생성한다.
- 이동할 페이지에 대한 설정을 한다(BookShippingConfirmAction.java).
- 주문 확인 페이지로 이동한다(bookShippingConfirm.jsp.jsp).
로직 흐름 코드 및 실행화면
1. 주문 페이지(bookShippingCheckOut.jsp)
1-1. ▼ 주문 페이지
요청된 URL은 http://localhost:8090/bookShippingCheckOut.ok 이다.
배송 정보 영역에 배송지 및 사용자 정보를 입력하고 결제하기 버튼을 누른다.
1-2. ▼ 주문 페이지 HTML
배송지를 입력하고 결제하기 버튼을 누르면 JS 함수가 호출된다.
<section>
<div>
<div>
<div class="row">
<div class="col-lg-8">
<h3>배송 정보</h3>
<form action="${request.getContextPath()}/bookShippingConfirm.ok" method="post"
name="shippingForm" novalidate="novalidate">
<div class="col-md-12 form-group p_star">
<input type="text" class="form-control" id="m_name" name="m_name" placeholder="성명">
</div>
<div class="col-md-4 form-group p_star">
<input type="text" id="m_phone0" name="m_phone0" readonly="readonly" placeholder="010">
</div>
<div class="col-md-4 form-group p_star">
<input type="text" id="m_phone1" name="m_phone1" placeholder="가운데 연락처">
</div>
<div class="col-md-4 form-group p_star">
<input type="text" id="m_phone2" name="m_phone2" placeholder="연락처 마지막 4자리">
</div>
<div class="col-md-6 form-group p_star">
<input type="text" id="m_email" name="m_email" placeholder="이메일">
</div>
<div class="col-md-12 form-group p_star">
<select class="country_select" name="m_country">
<option value="choose" disabled="disabled">선택하세요</option>
<option value="한국" selected="selected">한국</option>
<option value="U.S.A">U.S.A</option>
</select>
</div>
<div class="col-md-12 form-group p_star">
<input type="text" id="m_postcode" name="m_postcode" placeholder="우편 번호">
</div>
<div class="col-md-12 form-group p_star">
<input type="text" id="m_addr1" name="m_addr1" placeholder="주소">
</div>
</form>
</div>
<div class="col-lg-4">
<div>
<h2>Your Order</h2>
<ul class="list">
<li><a href="#">Product <span>Total</span></a></li>
<c:forEach items="${sessionScope.cartList }" var="cart">
<li>
<a href="#">${cart.c_b_name}
<span>x ${cart.c_b_qty}</span> <span>${cart.c_b_price * cart.c_b_qty}</span>
</a>
</li>
</c:forEach>
</ul>
<ul class="list list_2">
<li><a href="#">Subtotal <span>$ ${totalMoney}</span></a></li>
<li><a href="#">Shipping <span>Flat rate: $0.00</span></a></li>
<li><a href="#">Total <span>$ ${totalMoney}</span></a></li>
</ul>
<input type="submit" class="primary-btn" value="결제하기" onclick="javascript:sendShippingForm()"/>
<input type="button" class="primary-btn" value="이전으로" onclick="javascript:history.back(-1);">
</div>
</div>
</div>
</div>
</div>
</section>
1-3. ▼ 결제하기 버튼 JS 코드
sendShippingForm() 함수는 input 태그를 생성하고 form 태그에 붙인 후 form을 서버에 전송하는 역할을 수행한다.
input 태그가 될 변수 $input엔 이전과 마찬가지로 세션 쿠키를 담는다.
<script type="text/javascript">
function sendShippingForm() {
var $input = $('<input>').attr({
type: 'hidden',
name: 'c_session',
value: $.cookie('c_session')
});
$('form[name="shippingForm"]').append($input);
document.shippingForm.submit();
}
</script>
2. 컨트롤러(BookFrontController.java)
기존 BookFrontController 클래스에 아래 코드를 추가한다.
// 주문 완료 페이지
else if(command.equals("/bookShippingConfirm.ok")) {
action = new BookShippingConfirmAction();
try {
forward = action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
3. Action 클래스(BookShippingCheckOutAction.java)
- 세션을 확인한 후 URL에서 전송된 파라미터(세션쿠키)와 비교한다.
- 같은 세션 Id인 경우 장바구니 속성을 가져오고 총금액을 계산한다.
- 사용자가 입력한 정보를 쿠키로 생성한다.
- 페이지 이동 설정을 한다.
- 이동할 페이지 : /book/bookShippingConfirm.jsp
- 이동할 방식 : forward
package action;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import vo.ActionForward;
import vo.Cart;
/** 주문 완료 후 페이지 요청을 처리하는 Action 클래스 */
public class BookShippingConfirmAction implements Action {
@Override
public ActionForward execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
req.setCharacterEncoding("UTF-8");
/* 파라미터 가져오기 */
String c_session = req.getParameter("c_session");
ArrayList<Cart> cartList = null;
int totalMoney = 0; // 지불해야 하는 총금액
int money = 0; // 장바구니 항목 하나에 대한 지불 금액
/* 요청 파라미터와 비교해 세션에 저장된 장바구니 목록 가져오기
* 1. 총금액 계산 */
HttpSession session = req.getSession(false);
if(session != null) {
// 세션이 생성되어 있는 경우
if(session.getId().equals(c_session)) {
// 같은 브라우저의 경우
cartList = (ArrayList<Cart>) session.getAttribute("cartList");
System.out.println(" B.ShippingCheckOut.A : cartList - "+cartList.size());
for(int i=0; i<cartList.size(); i++) {
money = cartList.get(i).getC_b_price() * cartList.get(i).getC_b_qty();
totalMoney += money;
}
} else {
// 같은 세션Id 아닌 경우
session.invalidate();
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.print("<script>");
out.print("alert('서로 다른 브라우저입니다.');");
out.print("location.href='/bookShopMain.ok';");
out.print("</script>");
out.close();
}
} else {
// 세션이 생성되지 않은 경우
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.print("<script>");
out.print("alert('잘못된 접근입니다.');");
out.print("location.href='/bookShopMain.ok';");
out.print("</script>");
out.close();
}
/* 폼 페이지에서 전송된 파라미터를 쿠키로 생성
* 생성한 쿠키의 유효 기간 : 24H(60*60*24)
* response 내장 객체의 addCookie()로 쿠키 등록(생성은 서버에서, 저장은 클라쪽에) */
Cookie m_name =
new Cookie("shipping_name", URLEncoder.encode(req.getParameter("m_name"), "UTF-8"));
Cookie m_phone1 =
new Cookie("shipping_phone1", URLEncoder.encode(req.getParameter("m_phone1"), "UTF-8"));
Cookie m_phone2 =
new Cookie("shipping_phone2", URLEncoder.encode(req.getParameter("m_phone2"), "UTF-8"));
Cookie m_email =
new Cookie("shipping_email", URLEncoder.encode(req.getParameter("m_email"), "UTF-8"));
Cookie m_country =
new Cookie("shipping_country", URLEncoder.encode(req.getParameter("m_country"), "UTF-8"));
Cookie m_postcode =
new Cookie("shipping_postcode", URLEncoder.encode(req.getParameter("m_postcode"), "UTF-8"));
Cookie m_addr1 =
new Cookie("shipping_addr1", URLEncoder.encode(req.getParameter("m_addr1"), "UTF-8"));
m_name.setMaxAge(60*60*24);
m_phone1.setMaxAge(60*60*24);
m_phone2.setMaxAge(60*60*24);
m_email.setMaxAge(60*60*24);
m_country.setMaxAge(60*60*24);
m_postcode.setMaxAge(60*60*24);
m_addr1.setMaxAge(60*60*24);
resp.addCookie(m_name);
resp.addCookie(m_phone1);
resp.addCookie(m_phone2);
resp.addCookie(m_email);
resp.addCookie(m_country);
resp.addCookie(m_postcode);
resp.addCookie(m_addr1);
/* 포워딩할 때 가져갈 정보 저장
* 총금액을 request 영역에 속성으로 공유
* 결제한 시간을 request 영역에 속성으로 공유
* .ok -> .jsp : forward
* */
req.setAttribute("totalMoney", totalMoney);
req.setAttribute("shippingDate",
DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT,
req.getLocale()).format(new Date()));
ActionForward forward = new ActionForward();
forward.setPath("/book/bookShippingConfirm.jsp");
forward.setRedirect(false);
return forward;
}
}
4. 주문 확인 페이지(bookShippingConfirm.jsp)
요청된 URL은 http://localhost:8090/bookShippingConfirm.ok 이다.
세션에 저장된 장바구니와 쿠키에 저장된 배송지 및 주문자 정보, 그리고 request 영역에 저장된 총금액 정보가 잘 출력된 것을 확인할 수 있다.
4-1. ▼ 주문 확인 페이지 HTML
<section>
<div>
<h3>Thank you. Your order has been received.</h3>
<div>
<div class="col-lg-4">
<div class="details_item">
<h4>Order Info</h4>
<ul class="list">
<li><a href="#"><span>Order number</span> : 60235</a></li>
<li><a href="#"><span>Date</span> : ${shippingDate} </a></li>
<li><a href="#"><span>Total</span> : $ ${totalMoney}</a></li>
<li><a href="#"><span>Payment method</span> : Check payments</a></li>
</ul>
</div>
</div>
<div class="col-lg-4">
<div class="details_item">
<h4>주문자 정보</h4>
<ul class="list">
<li><a href="#"><span>주문자</span> : <span id="shippingName"></span></a></li>
<li>
<a href="#">
<span>연락처</span> : <i>010</i> - <i id="shippingPhone1"></i> - <i id="shippingPhone2"></i>
</a>
</li>
<li><a href="#"><span>이메일 주소</span> : <span id="shippingEmail"></span></a></li>
</ul>
</div>
</div>
<div class="col-lg-4">
<div class="details_item">
<h4>배송 주소</h4>
<ul class="list">
<li><a href="#"><span>국가명</span> : <span id="shippingCountry"></span></a></li>
<li><a href="#"><span>도로명 주소</span> : <span id="shippingAddr1"></span></a></li>
<li><a href="#"><span>상세 주소</span> : <span id="shippingAddr2"></span></a></li>
<li><a href="#"><span>우편번호</span> : <span id="shippingPostcode"></span></a></li>
</ul>
</div>
</div>
</div>
<div>
<h2>Order Details</h2>
<div>
<table class="table">
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col">Quantity</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
<c:forEach items="${sessionScope.cartList }" var="cart">
<tr>
<td><p>${cart.c_b_name }</p></td>
<td><h5>x ${cart.c_b_qty}</h5></td>
<td><p>$ ${cart.c_b_qty * cart.c_b_price }</p></td>
</tr>
</c:forEach>
<tr>
<td><h4>Subtotal</h4></td>
<td><h5></h5></td>
<td><p>$ ${totalMoney }</p></td>
</tr>
<tr>
<td><h4>Shipping</h4></td>
<td><h5></h5></td>
<td><p>Flat rate: $00.00</p></td>
</tr>
<tr>
<td><h4>Total</h4></td>
<td><h5></h5></td>
<td><p>$ ${totalMoney }</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
4-2. ▼ 주문 확인 페이지 JS
쿠키에 담긴 정보를 디코딩해 출력시키기 위해 JS의 decodeURIComponent() 함수를 사용한 부분이다.
<script type="text/javascript">
window.onload = function() {
var shipping_name = "shipping_name";
var shipping_phone1 = "shipping_phone1";
var shipping_phone2 = "shipping_phone2";
var shipping_email = "shipping_email";
var shipping_country = "shipping_country";
var shipping_addr1 = "shipping_addr1";
var shipping_postcode = "shipping_postcode";
const cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.startsWith(shipping_name + "=")) {
shipping_name = decodeURIComponent(cookie.substring(shipping_name.length + 1));
document.getElementById("shippingName").innerHTML = shipping_name;
}
if (cookie.startsWith(shipping_phone1 + "=")) {
shipping_phone1 = decodeURIComponent(cookie.substring(shipping_phone1.length + 1));
document.getElementById("shippingPhone1").innerHTML = shipping_phone1;
}
if (cookie.startsWith(shipping_phone2 + "=")) {
shipping_phone2 = decodeURIComponent(cookie.substring(shipping_phone2.length + 1));
document.getElementById("shippingPhone2").innerHTML = shipping_phone2;
}
if (cookie.startsWith(shipping_email + "=")) {
shipping_email = decodeURIComponent(cookie.substring(shipping_email.length + 1));
document.getElementById("shippingEmail").innerHTML = shipping_email;
}
if (cookie.startsWith(shipping_country + "=")) {
shipping_country = decodeURIComponent(cookie.substring(shipping_country.length + 1));
document.getElementById("shippingCountry").innerHTML = shipping_country;
}
if (cookie.startsWith(shipping_addr1 + "=")) {
shipping_addr1 = decodeURIComponent(cookie.substring(shipping_addr1.length + 1));
// '+'을 빈공백으로 치환
shipping_addr1 = shipping_addr1.split('+').join(' ');
console.log(shipping_addr1);
document.getElementById("shippingAddr1").innerHTML = shipping_addr1;
document.getElementById("shippingAddr2").innerHTML = shipping_addr1;
}
if (cookie.startsWith(shipping_postcode + "=")) {
shipping_postcode = decodeURIComponent(cookie.substring(shipping_postcode.length + 1));
document.getElementById("shippingPostcode").innerHTML = shipping_postcode;
}
}
}
</script>
♠ JS에서의 디코딩 처리 참고 ♠
2023.04.01 - [JSP/MVC] - [JSP] [MVC] [JS] [Cookie] MVC 패턴과 자바스크립트로 쿠키(Cookie) 가져오기
[JSP] [MVC] [JS] [Cookie] MVC 패턴과 자바스크립트로 쿠키(Cookie) 가져오기
스크립트 태그를 지양하고 MVC 패턴을 지키면서 웹 서버에서 생성한 쿠키를 웹 브라우저에서 출력하기 위해 노력한 결과물을 기록하고자 한다. 목표 ♠ JSP에서 MVC 패턴을 지키면서 서버에서 생
persimmon-ary-stepbystep.tistory.com
4-3. ▼ 주문 확인 페이지 쿠키 확인
이렇게 주문 페이지와 주문 확인 페이지를 구현함을 끝으로 세션으로 장바구니를 구현하는 로직이 완성되었다.
끝.
'JSP > MVC' 카테고리의 다른 글
[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 |
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #3. 장바구니 목록 구현하기 (0) | 2023.05.16 |
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #2. 장바구니 추가 구현하기 (0) | 2023.05.15 |
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #1. 구현 흐름 정리하기 (0) | 2023.05.15 |