[BOOK 개인프로젝트] 5. 홈 화면에 외부 링크 연동 및 홈화면 -> 장바구니, 찜 하기 상품 저장

이재민·2024년 6월 1일
0

JPA 

목록 보기
7/21
post-thumbnail

1. 홈 화면에 외부 링크 연동 (버튼을 통해 접근)

먼저 홈 화면에서 상품들을 그리드 형식으로 작성하였고 여기서 "View" 버튼을 통해 네이버 쇼핑으로 넘어가도록 계획함.

bodyHeader.html 일부

<div class="card shadow-sm">
<img class="bd-placeholder-img card-img-top" th:src="@{../images/자바 ORM 표준 JPA 프로그래밍.jpeg}" alt="자바 ORM 표준 JPA 프로그래밍" style="width: auto; height: 502px;">
<div class="card-body">
<p class="card-text"><strong>자바 ORM 표준 JPA 프로그래밍</strong><br>(스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임워크)</br></p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group d-flex justify-content-center align-items-center">
<a href="https://search.shopping.naver.com/book/catalog/32436007738"
class="btn btn-sm btn-outline-secondary" style="height: 33px; font-size: 14px; margin-left: 10px; min-width: 100px; vertical-align: middle;">View</a>

여기서

<a href="https://search.shopping.naver.com/book/catalog/32436007738"

여기서 href를 통해 링크를 삽입하여 버튼을 눌렀을 시 그 링크로 들어가게 하도록 함.

이렇게 네이버 쇼핑으로 넘어갔으면 성공!

2. 홈 화면 -> 장바구니 상품 저장

아까 첫 번째 사진(홈 화면)에서 basket 버튼을 통해 장바구니에 상품 저장하도록 함.

bodyHeader.html

<form id="addToBasketForm1" action="/home/basket" method="GET">
<button id="addToBasketButton1" class="btn btn-sm btn-outline-secondary" style="height: 33px; font-size: 14px; min-width: 100px;">Basket</button>
<input type="hidden" id="isbnInput1" name="isbn" value="9788960777330">
</form>

BasketController.java

  // isbn을 통해 찾은 book을 db에 저장 (web 화면 : from 홈화면 to 장바구니)
    @GetMapping("/home/basket")
    public String addToBasket(@RequestParam("isbn") String isbn) throws Exception {

        log.info("BasketController 실행합니다");

        log.info("장바구니에 상품 추가 요청을 받았습니다. ISBN: {}", isbn);

        // 네이버 책 검색 API를 통해 해당 ISBN에 해당하는 책 추출
        Book book = naverApiService.searchBookByIsbn(isbn);

        if (book.getTitle() == null || book.getIsbn() == null) {
            // 유효성 검사 실패 시 적절한 응답 반환
            log.error("북 이름, isbn이 필요합니다.");
            throw new Exception("북 이름, isbn 값이 필요합니다");
        }

        try {
            log.info("책 정보를 db에 저장합니다.");
            //책 정보를 db에 저장
            bookService.saveBook(book);

            // 적절한 응답 반환
            return "redirect:/home";

        } catch (DuplicateIsbnException e) {
            // 중복된 ISBN이 발생한 경우 적절한 응답 반환
            log.error("중복된 ISBN이 발생했습니다: {}", e.getMessage());
            throw new DuplicateIsbnException("해당 책이 이미 장바구니에 존재합니다.");

        } catch (Exception e) {
            // 저장 중에 예외가 발생한 경우 적절한 응답 반환
            log.error("저장 중 예외가 발생하였습니다.");
            throw new Exception("예상치 못한 예외가 발생했습니다 다시 시도해주세요.");
        }
    }

네이버 책 api를 통해 넘겨받은 isbn으로 책을 찾은 후 그 책을 장바구니에 저장하고, 책이 이미 장바구니에 존재하거나(중복 저장), 예외가 터지면 예외를 던진다.

NaverApiService.java - 네이버 검색 api 사용

   @Transactional
    public Book searchBookByIsbn(String isbn) throws Exception {

        log.info("NaverApiService _ searchBookByIsbn 실행");
        // 요청 헤더 설정
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-Naver-Client-Id", clientId);
        headers.set("X-Naver-Client-Secret", clientSecret);

        // API 호출을 위한 URI 생성
        URI uri = UriComponentsBuilder
                .fromUriString("https://openapi.naver.com")
                .path("/v1/search/book")
                .queryParam("query", isbn)
                .encode()
                .build()
                .toUri();

        // API 호출을 위한 요청 객체 생성
        RequestEntity<Void> req = RequestEntity
                .get(uri)
                .headers(headers)
                .build();

        // API 호출하여 응답 받기
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> resp = restTemplate.exchange(req, String.class);

        //body 확인 - 정상 작동
        log.info("Response Body: {}", resp.getBody());

        if (resp.getBody() == null) {
            log.error("응답 본문이 비워져 있습니다.");
            throw new Exception("응답 본문이 비워져 있습니다");
        }
        List<BookItem> bookItems = parseBook.parseBookInfo(resp.getBody());

        // 응답 본문 파싱하여 BookVO 객체로 변환 후 최종적으로 Book 객체로
        log.info("응답 본문을 파싱하여 BookVO 객체로 변환합니다.");
        Book book = new Book();
        if (!bookItems.isEmpty()) {
            BookVO bookVO = new BookVO();
            bookVO.setItems(bookItems);

            //BookV0 객체를 Book 객체로 변환
            log.info("BookV0 객체를 Book 객체로 변환");
            book = bookService.createBookFromBookVO(bookVO);
            log.info("변환된 Book 객체 : {}", book);
        }
        return book;
    }

정상 처리시

예외 시

3. 홈 화면 -> 찜 목록 상품 저장

bodyHeader.html 일부

<form id="addToBasketForm1_1" action="/savedBookinWishlist" method="GET">
<button id="addToBasketButton1_1" class="btn btn-sm btn-outline-secondary" style="height: 33px; font-size: 14px; min-width: 100px;">찜 하기</button>
<input type="hidden" id="isbnInput1_1" name="isbn" value="9788960777330">
</form>

WishlistController.java

    //api book isbn을 통해 db에 저장
    @GetMapping("/savedBookinWishlist")
    public String addToWishlist(@RequestParam("isbn") String isbn) throws Exception {

        //isbn -> 네이버 책 검색 API에 요청 보냄

        log.info("savedBookinWishlist");
        //Json 객체 -> book 객체로 convert
        Book book = naverApiService.searchBookByIsbn(isbn);

        log.info("변환된 Book 객체 : {}", book);

        Wishlist wishlist = WishlistService.convertToEntityWishlistBook(book);

        log.info("변환된 Wishlist 객체 : {}", wishlist);

        if (wishlist.getName() == null || wishlist.getIsbn() == null) {
            // 유효성 검사 실패 시 적절한 응답 반환
            log.error("북 이름, isbn이 필요합니다.");
            throw new Exception("북 이름, isbn 값이 필요합니다");
        }

        try {
            log.info("책 정보를 wishlist db에 저장합니다.");
            //책 정보를 db에 저장
            wishlistService.saveWishlist(wishlist);

            // 적절한 응답 반환
            return "redirect:/home";

        } catch (DuplicateWishlistException e) {
            // 중복된 ISBN이 발생한 경우 적절한 응답 반환
            log.error("이미 찜 목록에 상품이 존재합니다.: {}", e.getMessage());
            throw new DuplicateWishlistException("이미 찜 목록에 상품이 존재합니다.");

        } catch (Exception e) {
            // 저장 중에 예외가 발생한 경우 적절한 응답 반환
            log.error("저장 중 예외가 발생하였습니다.");
            throw new Exception("장바구니에 이미 해당 책이 있습니다.", e);
        }
    }

아까 장바구니와 비슷한 로직으로 처리

  1. 정상 처리
  2. 예외 처리
profile
복학생의 개발 일기

0개의 댓글

관련 채용 정보