1 분 소요

특정 게시글을 조회할 때, 조회 수가 중복으로 카운트 되지 않도록 쿠키를 이용해 구현해보자.

서버

PostServiceImpl.java

@Override
@Transactional
public DetailedPostInfoDto getDetailedPostInfo(Long postId, HttpServletRequest request,
    HttpServletResponse response) {

    Post post = getPost(postId);

    // 조회 수 중복 방지
    Cookie oldCookie = null;
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("postView")) {
                oldCookie = cookie;
            }
        }
    }
    if (oldCookie != null) {
        if (!oldCookie.getValue().contains("[" + postId.toString() + "]")) {
            updateViewCnt(post);
            oldCookie.setValue(oldCookie.getValue() + "_[" + postId + "]");
            oldCookie.setPath("/");
            oldCookie.setMaxAge(60 * 60 * 24);
            response.addCookie(oldCookie);
        }
    } else {
        updateViewCnt(post);
        Cookie newCookie = new Cookie("postView", "[" + postId + "]");
        newCookie.setPath("/");
        newCookie.setMaxAge(60 * 60 * 24);
        response.addCookie(newCookie);
        System.out.println(newCookie);
    }

    return new DetailedPostInfoDto(post);
}

private void updateViewCnt(Post post) {
    post.setViewCnt(post.getViewCnt() + 1);
}

조회수를 올리는데 쿠키를 활용하기 위해 request, response를 파라미터에 추가했다.

  1. oldCookie 객체를 선언한 후 빈값으로 초기화
  2. request 객체에서 쿠키들을 가져와 Cookie 타입을 요소로 가지는 리스트에 담는다.
  3. cookies가 null이 아닌지 체크한다.
  4. cookies가 null이 아니면 for문을 돌려서 cookie의 이름이 postView인지 확인하고, 맞으면 oldCookie에 이 cookie를 대입한다.
  5. oldCookie가 null이 아닐때
    - oldCookie의 value중 게시물의 id 값이 없을 때 (있다면 이미 조회한 게시물로 조회수가 올라가지 않음) 조회수 올리는 메소드 호출
    - oldCookie에 경로, 쿠키유지 시간을 추가하여 response에 oldCookie 를 전달한다.
  6. oldCookie가 null일 때
    - 조회수 올리는 메소드 호출
    - postView라는 이름으로 쿠키를 만들고 거기에 게시물 id 값을 괄호로 감싸 추가한다.
    - 마찬가지로, 쿠키유지 시간을 추가하여 response에 oldCookie 를 전달한다.

클라이언트

post-details.js

// 게시글 상세 읽기
function getPost() {
    ...
    $.ajax({
        type: 'GET',
        url: process.env.BACKEND_HOST + '/post/' + params['id'],
        xhrFields: {
            withCredentials: true
        },
        ...
    });
}

서버는 8080, 클라이언트는 3000번을 쓰기 때문에 서로 출처가 다르다.
이렇게 되면 쿠키를 통해 통신을 할 수 없다. (클라이언트에서 서버로 요청 시, 자동으로 쿠키가 요청 메시지에 담기지 않음)

이를 해결하기 위해 xhrFields: { withCredentials: true }를 추가해주어야 한다.
이는 클라이언트와 서버가 쿠키 값을 공유하겠다는 의미이다.
(서버에서 쿠키를 보내기 때문에, 사용하기 위해선 클라이언트에서 쿠키로 통신하는 것을 허락해야 한다.)

Ref.



💛 개인 공부 기록용 블로그입니다. 👻

맨 위로 이동하기

태그:

카테고리:

업데이트: