[Spring][쇼핑몰 프로젝트][35] 상품 상세 페이지 - 1
프로젝트 Github : https://github.com/sjinjin7/Blog_Project
프로젝트 포스팅 색인(index) : https://kimvampa.tistory.com/188
목표
상품 상세 페이지
상품 검색 페이지 혹은 다른 경로를 통하여 이동할 수 있는 '상품 상세 페이지' 구현을 목표로 하고, 이번 포스팅에서는 '상품 상세 페이지'의 서버 측 구현을 목표로 합니다.
순서
1. 방향
2. Mapper메서드
3. Service 메서드
4. Controller
1. 방향
전체적인 구현 방식은 앞서 구현했던 관리자 페이지 에서의 '상품 상세 페이지'와 다르지 않습니다. 하지만 이번 구현에서는 Spring에서 제공하는 @PathVariable 어노테이션 기능을 사용하여 구현해보겠습니다.
앞서 우리가 구현했던 '관리자 상품 상세 페이지' url경로를 보면 "/admin/goodsDetail"입니다. 지정한 상품의 상품 페이지로 들어가기 위해서 식별자 값("bookId")을 파라미터 형식("? bookId=1")으로 지정해주었습니다.
Spring의 @PathVariable 어노테이션 기능을 사용하게 된다면 '식별자 값'을 파라미터로 넘기지 않고 URL 경로에 삽입할 수 있게 됩니다. 사용법은 해당 구현 부분에서 간단히 설명하며 진행하겠습니다.
@PathVarialbe 사용 경우
"goodsDetail/61?pageNum=1&amount=10&keywod="
구현 작업 순서는 서버, 뷰 순으로 진행을 하겠습니다.
2. Mapper 메서드
클라이언트가 상품 상세 페이지 요청을 하면, 사용자가 지정한 '상품 정보'가 포함된 '상품 상세 페이지'를 전송해주어야 합니다. 그렇다면 어떠한 '상품 정보'를 전송해주어야 할지 결정해야 하는데 우리가 앞서 작성해둔 "BookVO"클래스에서 지정한 필드들의 값을 채워서 뷰(View)로 전송해주도록 하겠습니다. 따라서 "BookVO" 객체의 값을 채워서 반환해주는 Mapper 메서드를 먼저 작성하겠습니다.
BookMapper 인터페이스에 아래의 메서드 선언부를 추가해줍니다.
/* 상품 정보 */
public BookVO getGoodsInfo(int bookId);
사용자가 어떠한 상품을 원하는지 식별할 수 있는 bookId를 파라미터로 지정을 하였고, 반환 값은 BookVO객체로 지정해주었습니다.
"BookMapper.xml"에 인터페이스에서 선언한 메서드가 실행할 쿼리문을 작성해줍니다.
<!-- 상품 정보 -->
<select id="getGoodsInfo" resultType="com.vam.model.BookVO">
select a.BOOKID, a.BOOKNAME, a.AUTHORID, b.AUTHORNAME, a.PUBLEYEAR, a.PUBLISHER, a.CATECODE, c.CATENAME, a.BOOKPRICE, a.BOOKSTOCK, a.BOOKDISCOUNT, a.BOOKINTRO, a.BOOKCONTENTS
from vam_book a left outer join vam_author b on a.authorId = b.authorId
left outer join vam_bcate c on a.catecode = c.catecode
where bookid = ${bookId}
</select>
요구하는 데이터는 대부분 "vam_book" 테이블에 있긴 하지만 'authorName', 'cateName'은 "vam_author", "vam_bcate"에 있기 때문에 "LEFT OUTER JOIN"을 사용하여 3개의 테이블을 조인(JOIN) 하였습니다. ( JOIN에 대해 잘 모르신다면 "SQL 조인" 키워드로 구글링 하시거나 유튜브 검색을 하신다면 많은 자료를 보실 수 있습니다.)
작성한 Mapper 메서드가 정상적으로 동작하는지 확인하기 위해서 "BookMapperTests.java" 클래스에 아래의 코드를 작성하여 Junit 테스트를 하였습니다.
/* 상품 정보 */
@Test
public void getGoodsInfo() {
int bookId = 26;
BookVO goodsInfo = mapper.getGoodsInfo(bookId);
System.out.println("===========================");
System.out.println(goodsInfo);
System.out.println("===========================");
}
3. Service 메서드
Service 메서드를 작성해 줄 차례인데, 단순히 우리가 앞서 작성한 "getGoodsInfo()"메서드만을 호출하지 않고 "getGoodsInfo()"메서드가 반환해준 BookVO객체에 이미지 정보 데이터들을 추가하기 위해서 'imageList' 변수에 값을 부여해주는 작업을 해줄 것입니다.
따라서 이미지 정보를 호출하는 Mapper 메서드가 필요로 합니다. 그런데 이러한 작업을 해주는 AdminMapper 클래스의 "getAttachInfo()" 메서드가 있습니다. 따라서 이 메서드를 그대로 활용하여 작업을 하겠습니다.
먼저 BookService.java 인터페이스에 아래의 메서드를 추가해줍니다.
/* 상품 정보 */
public BookVO getGoodsInfo(int bookId);
BookServiceImpl.java에 인터페이스에서 선언한 메서드를 오버라이딩 하기앞서서 AdminMapper 클래스의 메서드를 사용해야 하기 때문에 아래의 코드를 추가하여 'AdminMapper' 객체를 의존성 주입해주었습니다.
@Autowired
private AdminMapper adminMapper;
인터페이스에서 선언한 메서드를 오버라이딩 하여 코드를 추가해주고, "getGoodsInfo()" 메서드를 호출하여 반환받은 BookVO객체를 리턴해주는 코드를 추가해줍니다.
@Override
public BookVO getGoodsInfo(int bookId) {
BookVO goodsInfo = bookMapper.getGoodsInfo(bookId);
return goodsInfo;
}
BookVO 객체에 이미지 정보 또한 추가해주어야 하기 때문에 아래의 코드를 추가해줍니다.
goodsInfo.setImageList(adminMapper.getAttachInfo(bookId));
작성한 Service 메서드가 정상적으로 동작하는지 확인하기 위해서 "BookServiceTests.java" 클래스에 아래의 코드를 추가하여 Junit 테스트를 해주었습니다.
확인해줄 상황은 상품 정보가 의도대로 반환이 되는지, 이미지가 있는 상품의 경우 '이미지 데이터' 또한 반환이 되는지 확인을 합니다.
/*상품 상세 정보*/
@Test
public void getGoodsInfoTest() {
int bookId = 2;
BookVO goodsInfo = service.getGoodsInfo(bookId);
System.out.println("==결과==");
System.out.println("전체 : " + goodsInfo);
System.out.println("bookId : " + goodsInfo.getBookId() );
System.out.println("이미지 정보 : " + goodsInfo.getImageList().isEmpty());
}
4. Controller
BookController.java 클래스에 작업을 해주겠습니다.
"상품 상세 페이지"의 URL은 "goodsDetail/상품 식별자" 형식으로 할 것입니다. "상품 상세 페이지" URL매핑 메서드를 아래와 같은 형식으로 작성해줍니다.
/* 상품 상세 */
@GetMapping("/goodsDetail/{bookId}")
public String goodsDetailGET(@PathVariable("bookId")int bookId, Model model) {
logger.info("goodsDetailGET()..........");
return "/goodsDetail";
}
구현부에는 'goodsDetail.jsp(아직 생성하지는 않았습니다.)'에 getGoodsInfo() 메서드를 호출하여 반환받은 BookVO객체를 Model 객체를 활용하여 넘겨주는 코드를 작성해줍니다.
/* 상품 상세 */
@GetMapping("/goodsDetail/{bookId}")
public String goodsDetailGET(@PathVariable("bookId")int bookId, Model model) {
logger.info("goodsDetailGET()..........");
model.addAttribute("goodsInfo", bookService.getGoodsInfo(bookId));
return "/goodsDetail";
}
@GetMapping 어노테이션을 보시면 Spring에서 사용자가 전송한 식별자 값을 변수로 인식하도록 하기 위해 템플릿 변수({bookId})를 작성해주었습니다.
URL로 전달받은 식별자 값을 인수로 전달받기 위해서 getDetailGET() 메서드의 파라미터에 변수를 선언해주고 파라미터 변수 앞에 @PathVarialbe 어노테이션을 추가해줍니다. 그리고 @PathVariable 어노테이션 파라미터로 앞서 @GetMapping에 작성한 템플릿 변수명을 추가해주면 됩니다.
만약 클라이언트가 "/goodsDetail/15" URL 경로로 요청을 하면 우라기 작성한 URL 매핑 메서드(goodsDetailGET())가 매핑되어 호출되고 @PathVarialbe 어노테이션을 통해 URL 경로에 작성된 식별자 값 "15"가 추출되어 파라미터 변수 'bookId'로 대입되어 값을 사용할 수 있게 됩니다.
REFERENCE
- 코드로배우는 스프링 웹 프로젝트(남가람북스)
DATE
- 2020.11.09