점프 투 스프링부트 추가기능 구현 - 조회수(수정 전 버전)

박철현·2023년 7월 26일
0

점프투스프링부트

목록 보기
1/14

점프투스프링부트 3-15 추가기능

  • 첫 번째로 조회수 기능을 구현했습니다.

  • 단순 조회수 증가를 우선 구현했고, Ajax 통신으로 브라우저의 로컬스토리지를 확인하여 읽었던 질문글인지 확인합니다.

    • 확인 이후 읽지 않았던 질문이라면 조회수를 1 증가시키고, 리다이렉트 url을 전송합니다.
    • 만일 읽었던 질문이라면 조회수를 증가시키지 않고 리다이렉트 url을 전송합니다.
  • 추가 부분 코드는 아래와 같습니다.

    • question_list.html
      • th:text="${question.view}" 로 조회수 표시
    <table class="table">
        <thead class="table-dark">
        <tr class="text-center">
            <th>조회수</th>  // !!!!추가!!!
        </tr>
        </thead>
        <tbody>
        <tr class="text-center" th:each="question, loop : ${paging}">
            <td th:text="${question.view}"></td> // !!!!추가 - 조회수 !!
        </tr>
        </tbody>
    </table>
  • Ajax : 브라우저의 로케이션 스토리지를 활용하여 동일한 질문에 대해서는 1개만 증가하도록 구현하기 위함 (True / False 값을 보냄)
   <script th:inline="javascript">

        // 로컬스토리지에 해당 게시글 읽은적이 있는지 검사
        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 showQuestionDetail = (questionId) => {
            const isVisited = checkIdInLocalStorage(questionId);

            if (!isVisited) {
                addIdToLocalStorage(questionId);
                $.ajax({
                    // 요청방식: get
                    type: "get",
                    url: "/question/detail",
                    data: {
                        "questionId": questionId,
                        "isVisited" : false
                    },
                    success: function (fragment) {
                        // 성공 시 리다이렉트 url을 받으므로, 이동
                        location.href=fragment;
                    },
                    error: function (err) {
                        console.log("요청 실패", err);
                    }
                });
            }
            else {
                $.ajax({
                    type: "get",
                    url: "/question/detail",
                    data: {
                        "questionId": questionId,
                        "isVisited" : true
                    },
                    success: function (fragment) {
                        // 성공 시 리다이렉트 url을 받으므로, 이동
                        location.href=fragment;
                    },
                    error: function (err) {
                        console.log("요청 실패", err);
                    }
                });
            }
        }
    </script>
  • QuestionController.java

    • detail 메서드 -> 2개로 나눔

    • Ajax 통신 시 기존에 읽었었는지 확인하고 증가시켜주는 viewCheck + 상세 질문 페이지를 보여주는 detail메서드

    • viewCheck

	@GetMapping("/detail")
	@ResponseBody
	public String viewCheck(Model model, @RequestParam Integer questionId, @RequestParam Boolean isVisited, AnswerForm answerForm) {
		Question question = questionService.getQuestion(questionId);

		// 방문한 적이 없을때만 조회수 증가
		if(!isVisited) {
			questionService.updateQuestionView(question);
		}

		// Ajax에 리다이렉트 url 알려주기
		return "/question/detail/%d".formatted(questionId);
	}
  • datail
	@GetMapping("/detail/{id}")
	public String detail(Model model, @PathVariable Integer id, AnswerForm answerForm) {
		Question question = questionService.getQuestion(id);
		model.addAttribute("question", question);
		return "question/question_detail";
	}
profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글