[Spring] 게시글 조회수 중복 방지
Updated:
I. 개요
게시판에 있어서 조회수는 사용자가 읽고 싶은 글을 선택하는데에 중요한 지표가 된다.
하지만 단순히 게시글에 접근했다고 조회수를 모두 올려준다면, 새로고침만으로도 조회수를 끝없이 올릴 수 있다.
이렇듯 조회수를 임의로 조작하는 것은 커뮤니티에서 흔히 발생할 수 있는 일이므로, 방지해야할 필요가 있다고 생각했다.
II. 쿠키를 통한 구현
/**
조회수 중복 방지
**/
private void viewCountUp(Long id, HttpServletRequest request, HttpServletResponse response) {
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("[" + id.toString() + "]")) {
postService.viewCountUp(id);
oldCookie.setValue(oldCookie.getValue() + "_[" + id + "]");
oldCookie.setPath("/");
oldCookie.setMaxAge(60 * 60 * 24);
response.addCookie(oldCookie);
}
} else {
postService.viewCountUp(id);
Cookie newCookie = new Cookie("postView","[" + id + "]");
newCookie.setPath("/");
newCookie.setMaxAge(60 * 60 * 24);
response.addCookie(newCookie);
}
}
조회수 중복방지는 필요한 기능이지만, 완벽하게 차단해야 할만큼 중대한 사항은 아니라고 생각했고, 따라서 쿠키를 사용하기로 했다.
아래와 같은 로직으로 흘러간다.
HttpServletRequest
로부터 클라이언트의 쿠키를 가져온다. 먼저 쿠키가null
인지 검사하고, 그렇지 않다면foreach
를 통해 해당 쿠키들 중postView
라는 이름의 쿠키가 있는지 검사한다.
만약 존재한다면oldCookie
라는 이름으로 가져온다.oldCookie
가null
이 아니라면, 즉postView
가 존재한다면 해당 쿠키의value
가 현재 접근한 게시글의id
를 포함하고 있는지 검사한다.
만약 가지고있다면 아무일도 일어나지 않고(조회수가 증가하지 않고), 가지고있지 않다면postService
의viewCountUp
을 통해 해당 게시글의 조회수를 올려주고, 게시글id
를 괄호로 감싸oldCookie
에 추가하고HttpServletResponse
에게 전달한다.oldCookie
가null
이라면 마찬가지로postService
의viewCountUp
을 통해 게시글의 조회수를 올려주고, 해당 게시글id
를 괄호로 감싼 새로운 쿠키postView
를 생성하여HttpServletResponse
에게 전달한다.
괄호로 id
를 감싼 이유
해당 게시글을 이미 조회한적이 있는지 판단하는데에는 contains
를 사용했는데, 단순히 숫자만 사용한다면 문제가 생길 수 있다.
예를 들어, 이미 101번
게시글을 조회하여 postView
의 값이 101
이라고 하자.
이 때, 10번
게시글을 조회하려 한다면, postView
쿠키의 101
에 포함되어 있는 값이기 때문에 중복된 조회로 여기고 조회수가 증가하지 않을 것이다.
이를 방지하기 위해 숫자를 온전히 검사하고자 [101], [10]
과 같은 식으로 포장하여 검사 및 갱신하도록 하였다.
III. 시연
id
가 각각 1, 2인 게시글 두개가 있으며, 조회수는 1이고 쿠키는 존재하지 않는 상태이다.
먼저, id
가 1인 게시글에 접근했다. oldCookie
가 null
값이므로 postView
쿠키가 생성되고, value
로 [1]
을 가지게 된다.
기존 조회한 적이 없던 게시글이므로 정상적으로 조회수가 증가한다.
다음으로, id
가 2인 게시글에 접근했다. postView
를 oldCookie
로 가지고, [2]
를 포함하지 않으므로 value
에 [2]
를 추가하여 전달한다.
마찬가지로 조회한 적이 없던 게시글이므로 정상적으로 조회수가 증가했을 것이다.
다시 id
가 1인 게시글에 접근했다. postView
를 oldCookie
로 가지나, [1]
을 이미 포함하고 있으므로 쿠키에는 변화가 없다.
1번게시글은 두번 접근했음에도 조회수가 1만 올라간 모습을 볼 수 있다.
Leave a comment