Spring/Spring Web 관련
[SPRING MVC+SERVLET]중복 조회 방지용 쿠키 생성하기
일상코딩
2021. 12. 19. 22:16
/**
* 이미 조회한 게시물에 대해서 해당 게시물에 대한 중복 조회수 증가를 방지하는 메소드이다.<br>
* @param request
* @param response
* @param nttId - 게시물 id 값
*/
private void addViewedNttIdToCookie(final HttpServletRequest request, final HttpServletResponse response, final String nttId) {
Cookie accumulateNttIdCookie = Arrays
.stream(request.getCookies())
.filter(cookie -> cookie.getName().equals("alreadyViewNttId"))
.findFirst()
.orElseGet(() -> {
Cookie cookie = createAccNttIdCookie(nttId); // 조회수 중복 방지용 쿠키 생성
response.addCookie(cookie); // 생성한 쿠키를 response에 담는다.
bbsService.incrementNttRdCnt(nttId); // 조회수 증가 쿼리 수행
return cookie;
});
// 한번이라도 조회한 게시물에 대해서는 쿠키값에 해당 게시물의 nttId가 저장된다.
// 서로 다른 nttId에 대해서는 "/" 로 구분한다.
// ex) 000000000891/000000000890/000000000889
String cookieValue = accumulateNttIdCookie.getValue();
if(cookieValue.contains(nttId) == false) {
String newCookieValue = cookieValue + "/" + nttId;
response.addCookie(getRemainSecondForTommorow()); // 기존에 같은 이름의 쿠키가 있다면 덮어쓴다.
bbsService.incrementNttRdCnt(nttId); // 조회수 증가 쿼리 수행
}
}
/**
* 조회수 중복 증가(= 새로고침에 의한 조회수 증가)를 방지하기 위한 쿠키를 생성하는 메소드 <br>
* 일반 게시판(공지사항, 자료실, 질의응답, FAQ, 사용자요청) 전용
* @param cookieValue
* @return
*/
private Cookie createAccNttIdCookie(String cookieValue) {
Cookie cookie = new Cookie("alreadyViewNttId", cookieValue);
cookie.setComment("조회수 중복 증가 방지 쿠키"); // 쿠키 용도 설명 기재
cookie.setMaxAge(getRemainSecondForTommorow()); // 하루를 준다.
cookie.setHttpOnly(true); // 클라이언트 단에서 javascript로 조작 불가
return cookie;
}
// 다음 날 정각까지 남은 시간(초)
private int getRemainSecondForTommorow() {
LocalDateTime now = LocalDateTime.now();
LocalDateTime tommorow = LocalDateTime.now().plusDays(1L).truncatedTo(ChronoUnit.DAYS);
return (int) now.until(tommorow, ChronoUnit.SECONDS);
}
참고1) 이 방식은 AJAX 방식으로 해도 된다. 비동기적으로 Cookie에 값이 채워지는 것이 보일 것이다.
@RequestMapping(value = "/incrementBbsRdCnt.do")
@ResponseBody
public void incrementBbsRdCnt(String id, HttpServletRequest request, HttpServletResponse response) {
addAlreadyViewedBbsIdToCookie(request, response, id);
}
더보기
참고2) 안전하지는 않다...
당연하지만, 사용자가 개발자 도구를 열어서 해당 쿠키를 지우면 조회수가 중복 증가하게 된다.
이건 쿠키 방식을 사용하면 어쩔 수 없다.
가장 궁극적인 안전한 방법은 디비를 사용하는 것이다.