[스프링부트] 찜목록 구현

최경현·2023년 12월 25일
0

프로젝트 진행 도중 찜 목록 구현하였음

찜목록 구현을 위한 service 구문 작성

public boolean toggleHeart(Long id, String username) {
        Optional<Member> memberOptional = findByUsername(username);
        Optional<Wine> wineOptional = wineRepository.findById(id);

            Member member = memberOptional.get();
            Wine wine = wineOptional.get();

            boolean isLiked = wine.getMember().contains(member);

            if (isLiked) {
                wine.getMember().remove(member);
            } else {
                wine.getMember().add(member);
            }
            wineRepository.save(wine);

            return !isLiked;
    }

controller 구문 작성

 @PreAuthorize("isAuthenticated()")
    @PostMapping("/toggleHeart/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Boolean>> toggleHeart(Model model, Principal principal, @PathVariable("id") Long id) {
        boolean isLiked = this.memberService.toggleHeart(id, principal.getName());
        Map<String, Boolean> response = new HashMap<>();
        response.put("isLiked", isLiked);

        return ResponseEntity.ok(response);
    }

    @PostMapping("/csrf/ajax")
    @ResponseBody
    public CsrfVO csrfAJAXSubmit(@RequestBody CsrfVO csrfVO) {

        return csrfVO;
    }

찜 값을 전달하는 과정에서 csrf오류가 자꾸 발생하여서 따로 처리를 진행하였음.

html구문 작성

 <div class="text-end">
                            <button type="button" onclick="toggleHeart(this)" sec:authorize="isAuthenticated()"
                                    th:data-wine-id="${wine.id}"
                                    class="text-white bg-red-800 hover:bg-red-900 focus:outline-none focus:ring-4 focus:ring-gray-300 rounded-lg text-2xl px-4 my-4 py-2.5 me-2 mb-2">
                                <div id="heartIcon">
                                    <p th:inline="text" th:if="${isLiked}"></p>
                                    <p th:inline="text" th:unless="${isLiked}"></p>
                                </div>
                            </button>
                        </div>

이미 찜 된 값이면 되었다고 표시하기 위해 구문을 나누어서 저장

값을 실시간으로 전달하기 위해 ajax를 이용 및 오류방지를 위해 csrf토큰값 부여

 function toggleHeart(button) {
        var token = $("meta[name='_csrf']").attr("content");
        var header = $("meta[name='_csrf_header']").attr("content");
        var name = $("#username").val();
        var heartIcon = button.querySelector("#heartIcon");
        var wineId = button.getAttribute("data-wine-id");

        var jsonData = {
            "name": name
        }

        $.ajax({
            type: 'POST',
            contentType: "application/json",
            url: "/article/toggleHeart/" + wineId,
            data: JSON.stringify(jsonData), // String -> json 형태로 변환
            beforeSend: function (xhr) {   /*데이터를 전송하기 전에 헤더에 csrf값을 설정한다*/
                xhr.setRequestHeader(header, token);
            },
            dataType: 'json', // success 시 받아올 데이터 형
            async: true, //동기, 비동기 여부
            cache: false, // 캐시 여부
            success: function (data) {
                if (data.isLiked) {
                    heartIcon.textContent = "♥";
                } else {
                    heartIcon.textContent = "♡";
                }
            },
            error: function (xhr, status, error) {
                console.log('error:' + error);
            }
        });
    }
profile
ㅇㅇ

0개의 댓글