문제 : 게시글 목록에서 글 이동하면 조회수가 증가하지만, 사용자가
/detail/id 형태로 접속하면 증가가 안됨 -> Ajax 요청을 안보내니깐
해결 : detail.html에 Ajax 메서드 구현, Controller 메서드 2개 나눈거 다시 1개로 변경
<script th:inline="javascript">
window.onload = function () {
checkQuestionRead(); // html 로드 시 바로 Ajax 요청
};
// 로컬스토리지에 해당 게시글 읽은적이 있는지 검사
function checkIdInLocalStorage(id) {
const visitedPosts = JSON.parse(localStorage.getItem("visitedPosts") || "[]");
return visitedPosts.includes(id);
}
// 로컬스토리지에 방문 게시글 번호 추가
// null 일 경우 []값이 들어가고, push로 id넣고 새로 세팅(맨 처음)
function addIdToLocalStorage(id) {
const visitedPosts = JSON.parse(localStorage.getItem("visitedPosts") || "[]");
visitedPosts.push(id);
localStorage.setItem("visitedPosts", JSON.stringify(visitedPosts));
}
const checkQuestionRead = () => {
const questionId = [[${question.id}]];
// 방문 내역 검사
const isVisited = checkIdInLocalStorage(questionId);
// 방문하지 않았을 때만 추가하고 조회수 증가하도록
// true인 경우는 조건 제외함(요청 안보내도 되니)
if (!isVisited) {
addIdToLocalStorage(questionId);
$.ajax({
// 요청방식: get
type: "get",
url: "/question/detail/" + questionId,
data: {
"isVisited" : false
},
success: function (fragment) {
$('#questionDetail').html(fragment);
},
error: function (err) {
console.log("요청 실패", err);
}
});
}
}
</script>
@GetMapping("/detail/{id}")
public String detail(Model model, @PathVariable Integer id, @RequestParam(required = false) Boolean isVisited, AnswerForm answerForm, HttpServletRequest request) {
Question question = questionService.getQuestion(id);
// 방문한 적이 없을때만 조회수 증가
if (isVisited != null && !isVisited) {
questionService.updateQuestionView(question);
}
model.addAttribute("question", question);
// 요청에 AJAX 헤더가 있는 경우 부분 페이지 반환
if (Ut.AjaxUtils.isAjaxRequest(request)) {
return "question/question_detail :: #questionDetail";
}
return "question/question_detail";
}
public class Ut {
public static class AjaxUtils {
public static boolean isAjaxRequest(HttpServletRequest request) {
// Ajax 요청인지 검사
String header = request.getHeader("X-Requested-With");
return "XMLHttpRequest".equals(header);
}
}
}
@GetMapping("/increase")
@ResponseBody
public String increaseHit(Integer questionId, @RequestParam(required = false) Boolean isVisited) {
Question question = questionService.getQuestion(questionId);
// 방문한 적이 없을때만 조회수 증가
if (isVisited != null && !isVisited) {
questionService.updateQuestionView(question);
}
return Integer.toString(question.getView());
}
const checkQuestionRead = () => {
const questionId = [[${question.id}]];
// 방문 내역 검사
const isVisited = checkIdInLocalStorage(questionId);
// 방문하지 않았을 때만 추가하고 조회수 증가하도록
// true인 경우는 조건 제외함(요청 안보내도 되니)
if (!isVisited) {
addIdToLocalStorage(questionId);
$.ajax({
// 요청방식: get
type: "get",
url: "/question/increase",
data: {
"questionId" : questionId,
"isVisited" : isVisited
},
success: function (fragment) {
$('#questionView').text(fragment);
},
error: function (err) {
console.log("요청 실패", err);
}
});
}
별도 컨트롤러 메서드를 두고, 조회수 부분의 text만 변경하도록 수정
불필요하게 다른 부분까지 다 변경하는 부분이 없어져서 좋은듯