넘어온 상품 그리고 그 상품을 결제하기 위한 카드를 입력받아 주문한다!
OrderController
//주문하기
@PostMapping("/saveOrder")
public String saveOrder(HttpServletRequest request) {
String card_number = request.getParameter("Card_Number");
String expiryDate = request.getParameter("Expiry_Date");
String cvv = request.getParameter("CVV");
String cardHolder = request.getParameter("Card_Holder");
if (card_number == null || expiryDate == null || cvv == null || cardHolder == null) {
throw new IllegalArgumentException("모든 카드 정보가 필요합니다.");
}
log.info("Card_Number = {}, Expiry_Date = {}, CVV = {}, Card_Holder = {}",
card_number, expiryDate, cvv, cardHolder);
//빈 Order 객체에 주문 하기 db인 orderBook 객체를 넘김 (orderBook - 주문하기, order - 주문 내역)
List<OrderBook> orderBooks = orderBookRepository.orderBookList();
for (OrderBook orderBook : orderBooks) {
try {
orderManagementService.processOrder(card_number, expiryDate, cvv, cardHolder, orderBook);
} catch (DuplicateOrderException e) {
log.error("중복된 주문: {}", e.getMessage());
throw new DuplicateOrderException("중복된 주문입니다. 다시 한 번 확인해주세요.");
}
}
return "redirect:/home";
}
주문하기 화면에서 파라미터로 카드 값들을 받고, 먼저 카드 값이 하나라도 비워져있거나 중복된 주문일 경우 에러를 터트린다.
그리고 정상적으로 카드 값이 넘어왔을 경우, orderBook db에 있는 값들을 하나씩 뽑아내면서 "orderManagementService.processOrder" 메서드를 실행시킨다.
OrderManagementService
//order db에 상품 저장 orderbook db에서 상품 삭제
public void saveOrderAndDeleteOrderBook(Order order) {
try {
orderService.saveOrder(order);
orderBookService.deleteBook(order.getIsbn());
} catch (Exception e) {
log.error("주문 저장 및 주문 도서 삭제 중 오류가 발생했습니다: {}", e.getMessage());
//보상 트랜잭션 수행
compensateOrderManagement(order);
}
}
public void processOrder(String card_number, String expiryDate, String cvv, String cardHolder, OrderBook orderBook) {
Order order = new Order();
//주문 생성
Order findOrder = orderService.createOrder(order, card_number, expiryDate, cvv, cardHolder);
Order EndOrder = orderService.getOrderByOrderBook(findOrder, orderBook);
if (orderRepository.findByIsbn(EndOrder.getIsbn()) != null) {
throw new DuplicateOrderException("이 상품은 이미 주문되었습니다. 주문 내역을 확인하거나 다른 상품을 선택해주세요.");
}
saveOrderAndDeleteOrderBook(EndOrder);
}
private void compensateOrderManagement(Order order) {
try {
//주문 저장 성공했으나 주문 도서 삭제 실패 -> 저장된 주문 취소
orderBookService.deleteBook(order.getIsbn());
log.info("보상 트랜잭션 : 도서 취소 완료");
} catch (Exception e) {
log.info("보상 트랜잭션 중 오류가 발생했습니다 : {}", e.getMessage());
}
}
먼저 빈 주문 객체를 만든 후 createOrder 메서드를 통해 주문을 생성해준다. 그리고 "getOrderByOrderBook" 메서드를 통해 넘어온 orderBook 객체의 값들을 하나씩 생성한 order 객체에 담아준다.
그리고 그 값이 이미 주문하였었다면 오류를 터트리고 그렇지 않다면 주문 내역에 상품을 저장하면서 주문 하기에서 상품을 삭제한다.
또한 "주문하기에 상품 저장 + 주문 하기 페이지에서 상품 삭제" 두 가지가 원활하게 동작되지 않을 상황을 대비해 보상 트랜잭션을 적용한다.
OrderService
public Order createOrder(Order order, String card_number, String expiryDate, String cvv, String cardHolder) {
order.setCardNumber(card_number);
order.setExpiryDate(expiryDate);
order.setCvv(cvv);
order.setCardHolder(cardHolder);
return order;
}
public Order getOrderByOrderBook(Order findOrder, OrderBook orderBook) {
findOrder.setName(orderBook.getName());
findOrder.setPublisher(orderBook.getPublisher());
findOrder.setPrice(orderBook.getPrice());
findOrder.setAuthor(orderBook.getAuthor());
findOrder.setImage(orderBook.getImage());
findOrder.setLink(orderBook.getLink());
findOrder.setIsbn(orderBook.getIsbn());
findOrder.setCount(1); // 주문 수량은 1로 가정
findOrder.setPubdate(orderBook.getPubdate());
return findOrder;
}
상품이 잘 넘어왔다는 것을 알 수 있다.
OrderController
@GetMapping("/delete_order")
public String delete_order(@RequestParam("isbn") String isbn) {
log.info("주문 내역 페이지에서 상품을 삭제합니다.");
orderService.deleteOrder(isbn);
return "redirect:/home";
}
해당 로직을 적용해보면 상품이 삭제된다.