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를 통해 링크를 삽입하여 버튼을 눌렀을 시 그 링크로 들어가게 하도록 함.
이렇게 네이버 쇼핑으로 넘어갔으면 성공!
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;
}
정상 처리시
예외 시
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);
}
}
아까 장바구니와 비슷한 로직으로 처리