담당 기능
오늘은 리뷰 게시판 담당하고 계시는 팀원분의 게시글 조회수 기능 구현을 해보겠습니다.
보통 게시글 조회수를 구현할 때 쿠키/세션 중 하나를 선택해서 구현하는데, 프로젝트에 적용할 방식은 쿠키를 사용해서 구현해 보겠습니다.
Cookie는 브라우저에 접속했을 때 값을 저장하는 역할을 합니다.
개념에 대해서는 별도로 설명하는 포스팅이 아니라서 알아보시는 분들은 아래 포스팅을 참고해 보시면 좋을 거 같습니다.
프로젝트 구조는 다음과 같습니다.
프로젝트 구조
구현 결과
먼저 구현 결과를 보여드리자면
주요 기능은 아니지만, 게시판에 없어서는 안 되는 기능 중 하나가 조회수입니다.
그럼 어떻게 구현을 할까?
프로젝트 흐름을 설명하자면 리뷰 상세 페이지를 들어갔을 때, MVC 패턴을 거치고 쿠키 값을 저장해서 주회수 중복 방지를 할 수 있게 해야 하기 때문에 이전에 별점 기능을 구현했던 url mapping에 추가적으로 count 메서드를 구현합니다.
Controller
@GetMapping("/review/detail")
public ModelAndView detail(Integer review_num,
HttpServletRequest request,
HttpServletResponse response) {
//조회수 기능 추가
reviewService.count(review_num, request,response);
ReviewDTO review = reviewService.detail(review_num);
/*평점 total 값 추가 */
Double ratingavg = reviewService.ratingAvg(review_num);
ModelAndView mav = new ModelAndView();
mav.setViewName("review/detail");
mav.addObject("review", review);
/* 뷰단에 보내주기 */
mav.addObject("ratingAvg", ratingavg);
return mav;
}
조회수 기능을 추가하는 메서드를 구현했다면 service 단에서 코드 구현을 해야 합니다.
쿠키 기능에 반영될 비즈니스 로직을 service 단에서 구현합니다.
Service
public void count(Integer review_num, HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
boolean visited = false;
if (cookies != null) { // 배열이 null이 아니면
for (Cookie cookie : cookies) {
if (cookie.getName().equals("visit_cookie")) { // 쿠키 이름이 "visit_cookie"인 경우에만 내부 블록 실행
if (cookie.getValue().contains("_" + request.getParameter("review_num") + "_")) {// 쿠키 값 == 현재 리뷰 번호
visited = true;
break;
} else { // 포함하지 않은 경우
cookie.setValue(cookie.getValue() + "_" + request.getParameter("review_num") + "_");
cookie.setMaxAge(60 * 60); // 1시간 설정 (초 단위)
response.addCookie(cookie); // 클라이언트 전송
visited = true;
reviewDao.count(review_num); // 조회수 증가
break;
}
}
}
}
if (!visited) { // visited = false 인 경우
//review_num 파라미터 값 가져옴.
//새로운 cookie 생성
Cookie newCookie = new Cookie("visit_cookie", "_" + request.getParameter("review_num") + "_");
newCookie.setMaxAge(60 * 60); // 1시간 설정 (초 단위)
response.addCookie(newCookie);// 새로운 쿠키 응답 추가
reviewDao.count(review_num); // 조회수 증가
}
}
위 비즈니스 로직을 보면
먼저 request를 통해 쿠키를 가져옵니다.
만약에 쿠키가 존재하지 않으면 새로운 이름의 쿠키를 생성하고 조회수를 증가시켜 주거나, 가져온 쿠키의 value에 해당 review_num 값이 존재하지 않다면 추가시켜 준 후, 조회수를 증가시켜 줍니다.
다음으로는 mapper 연결을 시켜주는 DAO 파일을 생성합니다.
DAO
@Override
public void count(Integer review_num) {
sqlSession.update("review.count", review_num);
}
위 비즈니스 로직에서 필요한 건 review_num 값의 존재 여부입니다.
mapper 파일에 쿼리문 작성할 때 체크할 수 있게 review_num 값도 보내줍니다.
mapper
쿼리문은 간단합니다.
<!--조회수 증가-->
<update id="count">
update review
set readcount = readcount + 1
where review_num = #{review_num}
</update>
요청이 들어온 review_num 값이 존재하지 않다면 readcount +1 해줍니다.
쿼리문까지 작성이 완료되었다면 미리 생성해 두었던 review deteil.jsp 파일에 적용시켜 줍니다.
deteil.jsp
<div>
<p class="mb-0 h6"><img src="${pageContext.request.contextPath}/resources/images/logo.png" alt="mdo" width="32" height="32" class="rounded-circle">${review.member.mem_nickname}</p>
<div>
<small class="opacity-50 mb-0 text-nowrap">
<c:choose>
<c:when test="${review.edit_date == null}">
<fmt:formatDate value="${review.review_date}" pattern="yyyy-MM-dd HH:mm:ss"/>
</c:when>
<c:otherwise>
<fmt:formatDate value="${review.edit_date}" pattern="yyyy-MM-dd HH:mm:ss"/>
</c:otherwise>
</c:choose>
</small>
<%--조회수 기능 추가--%>
<small class="opacity-50 mb-0 ms-2 text-nowrap">${review.readcount}</small>
</div>
</div>
추가를 하면 앞서 보여드린 구현 결과 화면처럼 조회수가 올라가거나 , 중복 방지를 해주는 결과를 확인할 수 있습니다.
마치며
오늘은 리뷰게시판 - 조회수 기능 구현에 대해서 알아봤습니다.
다음 포스팅에서 뵙겠습니다.
'[ Project ] > Team' 카테고리의 다른 글
[ Team ] OAuth - KakaO API DB 연동 (0) | 2023.06.28 |
---|---|
[ Team ] OAuth - Naver API DB 연동 (0) | 2023.06.27 |
[ Team ] 리뷰게시판 - 별점 기능 구현 (0) | 2023.06.23 |
[ Team ] 인터셉터(Interceptor) 구현 (0) | 2023.06.21 |
[ Team ] 회원관리 - 페이지네이션 처리 기능 구현 (0) | 2023.06.20 |