본문 바로가기
[ Project ]/Team

[ Team ] 리뷰게시판 - 조회수 기능 구현

by 환이s 2023. 6. 26.


담당 기능

 

 

오늘은 리뷰 게시판 담당하고 계시는 팀원분의 게시글 조회수 기능 구현을 해보겠습니다.

보통 게시글 조회수를 구현할 때 쿠키/세션 중 하나를 선택해서 구현하는데, 프로젝트에 적용할 방식은 쿠키를 사용해서 구현해 보겠습니다.

 

 

Cookie는 브라우저에 접속했을 때 값을 저장하는 역할을 합니다.

개념에 대해서는 별도로 설명하는 포스팅이 아니라서 알아보시는 분들은 아래 포스팅을 참고해 보시면 좋을 거 같습니다.

 

 

[ JSP ] Cookie

이전 포스팅에서 JDBC 암호화 처리하는 방법까지 알아봤습니다! 오늘은 Cookie에 대해서 알아봅시다. ■ 쿠키란? 평소에 인터넷을 많이 하신 분이라면, 쿠키를 한 번쯤은 들어 보셨을 텐데, 쿠키는

drg2524.tistory.com

 

프로젝트 구조는 다음과 같습니다.

 

프로젝트 구조

 


구현 결과

 

먼저 구현 결과를 보여드리자면

 

 

주요 기능은 아니지만, 게시판에 없어서는 안 되는 기능 중 하나가 조회수입니다.

 

그럼 어떻게 구현을 할까? 

 

프로젝트 흐름을 설명하자면 리뷰 상세 페이지를 들어갔을 때, 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>

 

추가를 하면 앞서 보여드린 구현 결과 화면처럼 조회수가 올라가거나 , 중복 방지를 해주는 결과를 확인할 수 있습니다.

 


마치며

 

오늘은 리뷰게시판 - 조회수 기능 구현에 대해서 알아봤습니다.

다음 포스팅에서 뵙겠습니다.

 

 

728x90