팀프로젝트/SpringBoot

스프링부트 팀플) 20240321_익명 게시판의 익명 유저가 추천/비추천했는지를 저장하고 출력

일일일코_장민기 2024. 3. 21. 17:33
728x90

https://m.blog.naver.com/adamdoha/222081530284

 

[Java] 쿠키(Cookie) 생성, 조회, 삭제

서론 JWT로 회원 인증 처리를 할 때, 쿠키를 활용해볼 수도 있는데, 서비스를 개발할 때마다 자주 쓰이...

blog.naver.com

 

 

쿠키가 잘 저장된 모습

 

//게시판 글 보기

@GetMapping("/viewDBoardContent/{bNum}")

public ModelAndView viewDBoardContent(@PathVariable("bNum") int boardNum, HttpServletRequest request, HttpServletResponse response) throws ParseException {

 

//쿠키에 user 식별 key 있는지 확인

String userKey = "";

Cookie[] cookies = request.getCookies();

if (cookies != null) {

// System.out.println("userKey 탐색");

for (Cookie cookie : cookies) {

if (cookie.getName().equals("userKey")) {

userKey = cookie.getValue();

break; // 찾았으면 루프 종료

}

}

 

//글로 바로 들어왔을 경우, 사용자 식별을 위한 값을 쿠키에 저장

if(userKey == "") {

userKey = getNum();

Cookie key= new Cookie("userKey", userKey);

key.setMaxAge(60*60*24);

response.addCookie(key);

System.out.println("====userKey Cookie 생성====");

}

 

}

//System.out.println("userKey: " + userKey);

 

 

//현재 게시판에 접속한 유저가 추천을 눌렀는지 쿠키에서 출력

String LikeCookieKey = "K"+userKey+"N"+boardNum+"Like";

String userBylike = "";

cookies = request.getCookies();

if (cookies != null) {

// System.out.println("CookieKey 탐색");

for (Cookie cookie : cookies) {

if (cookie.getName().equals(LikeCookieKey)) {

userBylike = cookie.getValue();

break;

}

}

}

//System.out.println("recommendVal: "+ userBylike);

 

 

//현재 게시판에 접속한 유저가 비추천을 눌렀는지 쿠키에서 출력

String disLikeCookieKey = "K"+userKey+"N"+boardNum+"disLike";

String userBydislike = "";

cookies = request.getCookies();

if (cookies != null) {

// System.out.println("CookieKey 탐색");

for (Cookie cookie : cookies) {

if (cookie.getName().equals(disLikeCookieKey)) {

userBydislike = cookie.getValue();

break;

}

}

}

//System.out.println("disRecommendVal: "+ userBydislike);

 

ModelAndView mav = new ModelAndView();

 

//이전글 | 다음글 가져오기

DebugBoardDTO prev = prevPost(boardNum);

if(prev != null) { //마지막 글은 prev가 null값

prev.setEdittedDate(chooseDateForm(prev.getEdittedDate()));

}

DebugBoardDTO next = nextPost(boardNum);

if(next != null) { //가장 최신 글은 next가 null값

next.setEdittedDate(chooseDateForm(next.getEdittedDate()));

}

 

//날짜 형식 변경

DebugBoardDTO dto = serv.viewDBoardContent(boardNum);

dto.setEdittedDate(chooseDateForm(dto.getEdittedDate()));

 

mav.addObject("userBylike", userBylike);

mav.addObject("userBydislike", userBydislike);

mav.addObject("userKey", userKey);

mav.addObject("dto", dto);

mav.addObject("prev", prev);

mav.addObject("next", next);

mav.setViewName("member/Test/viewDBoardContent");

return mav;

}

 

//익명 유저가 게시판에 추천을 했는지 여부를 쿠키로 저장

@PostMapping("/increaseDBoardRecommendNum")

public int increaseDBoardRecommendNum(String userKey, int boardNum, String recommendVal, HttpServletRequest request, HttpServletResponse response) {

 

DebugBoardDTO dto = dServ.viewDBoardContent(boardNum);

int recommendNum = dto.getRecommendNum();

 

//페이지에서 불러온 현재 접속한 유저Key | 페이지 번호 | 좋아요 상태

//System.out.println("userKey: " + userKey);

//System.out.println("boardNum: "+ boardNum);

//System.out.println("recommendVal: "+recommendVal);

 

String LikeCookieKey = "K"+userKey+"N"+boardNum+"Like";

//System.out.println(LikeCookieKey);

 

if(recommendVal.equals("like")) {

dServ.increaseDBoardRecommendNum(boardNum);

dto = dServ.viewDBoardContent(boardNum);

recommendNum = dto.getRecommendNum();

 

Cookie key= new Cookie(LikeCookieKey, recommendVal);

key.setMaxAge(60*60*24);

response.addCookie(key);

//System.out.println("userKey에 따른 페이지 좋아요 Cookie 생성");

}

 

return recommendNum;

}

 

//익명 유저가 게시판에 비추천을 했는지 여부를 쿠키로 저장

@PostMapping("/decreaseDBoardRecommendNum")

public int decreaseDBoardRecommendNum(String userKey, int boardNum, String disrecommendVal, HttpServletRequest request, HttpServletResponse response) {

 

DebugBoardDTO dto = dServ.viewDBoardContent(boardNum);

int disRecommendNum = dto.getDisRecommendNum();

 

//페이지에서 불러온 현재 접속한 유저Key | 페이지 번호 | 좋아요 상태

//System.out.println("userKey: " + userKey);

//System.out.println("boardNum: "+ boardNum);

//System.out.println("disrecommendVal: "+disrecommendVal);

 

String disLikeCookieKey = "K"+userKey+"N"+boardNum+"disLike";

//System.out.println(disLikeCookieKey);

 

if(disrecommendVal.equals("dislike")) {

dServ.decreaseDBoardRecommendNum(boardNum);

dto = dServ.viewDBoardContent(boardNum);

disRecommendNum = dto.getDisRecommendNum();

 

Cookie key= new Cookie(disLikeCookieKey, disrecommendVal);

key.setMaxAge(60*60*24);

response.addCookie(key);

// System.out.println("userKey에 따른 페이지 싫어요 Cookie 생성");

}

 

return disRecommendNum;

}

 

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

 

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title></title>

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>

<!-- 외부 css 파일 -->

<link rel="stylesheet" type="text/css" href="<c:url value='/resources/css/member/unfound.css'/>">

<!-- 부트 스트랩 -->

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

 

</head>

<body>

 

 

<!-- 헤더 네비게이션바 -->

<div id="header">

<jsp:include page="/WEB-INF/views/common/navibarForMember.jsp" flush="true"></jsp:include><br>

</div>

<hr>

 

 

<!-- 출력되는 페이지 -->

<input type="hidden" id="userBylike" name="userBylike" value="${userBylike}">

<input type="hidden" id="userBydislike" name="userBydislike" value="${userBydislike}">

<input type="hidden" id="boardNum" name="boardNum" value="${dto.boardNum}">

<input type="hidden" id="userKey" name="userKey" value="${userKey}">

<input type="hidden" id="recommendNum" name="recommendNum" value="${dto.recommendNum}">

<input type="hidden" id="disRecommendNum" name="disRecommendNum" value="${dto.disRecommendNum}">

작성자: ${dto.nickname}

제목: ${dto.title}<br>

카테고리: ${dto.category}

작성 날짜: ${dto.edittedDate}

조회수: ${dto.viewCount}

추천수: <span id="resultRecommendNum">${dto.recommendNum - dto.disRecommendNum}</span>

<br>

<p>${dto.content}</p>

 

 

<!-- 추천 상태에 따른 이미지 출력 -->

<span>

<img src="<c:url value='/resources/images/member/well.svg'/>" width="50" height="50" id="recommendVal" data-val="like">

</span>

<span>

<img src="<c:url value='/resources/images/member/well.svg'/>" width="50" height="50" id="disrecommendVal" data-val="dislike">

</span>

<br>

 

 

<!-- post로 글 수정 / 삭제 / 목록 -->

<div>

<form action="<c:url value='/checkUpdatePost'/>/${dto.boardNum}" method="post" style="display: inline-block;">

<input type="submit" id="update" value="글 수정">

</form>

<form action="<c:url value='/checkDeletePost'/>/${dto.boardNum}" method="post" style="display: inline-block;">

<input type="submit" id="delete" value="글 삭제">

</form>

<form action="<c:url value='/viewDBoardList/boardNum'/>" method="get" style="display: inline-block;">

<input type="submit" id="list" value="글 목록">

</form>

</div>

<hr>

 

 

<!-- 이전글 / 다음글 출력 -->

<c:if test="${prev != null}">

<p>

이전 글:

글번호: ${prev.boardNum} | 카테고리: ${prev.category} |

제목: <span onclick="submitForm(${prev.boardNum})">${prev.title}</span> |

닉네임: ${prev.nickname} |

작성 날짜: ${prev.edittedDate} |

조회수: ${prev.viewCount} |

추천수: ${prev.recommendNum - prev.disRecommendNum}

</p>

</c:if>

<c:if test="${next != null}">

<p>

다음 글:

글번호: ${next.boardNum} | 카테고리: ${next.category} |

제목: <span onclick="submitForm(${next.boardNum})">${next.title}</span> |

닉네임: ${next.nickname} |

작성 날짜: ${next.edittedDate} |

조회수: ${next.viewCount} |

추천수: ${next.recommendNum - next.disRecommendNum}

</p>

</c:if>

 

 

<script type="text/javascript">

 

//익명 유저가 추천/비추천을 했을 경우, 그 상태 유지

$(function(){

 

if($("#userBylike").val() == "like"){

$("#recommendVal").attr("data-val", "likeChecked");

$("#recommendVal").attr("src", "<c:url value='/resources/images/member/like.svg'/>");

}

if($("#userBydislike").val() == "dislike"){

$("#disrecommendVal").attr("data-val", "dislikeChecked");

$("#disrecommendVal").attr("src", "<c:url value='/resources/images/member/dislike.svg'/>");

}

})

 

 

// 이전글, 다음글에서 제목을 누르면 세부글로 이동

function submitForm(boardNum) {

window.location.href ="<c:url value='/viewDBoardContent'/>/"+boardNum;

}

 

 

//추천을 위한 이미지 클릭 시 추천 숫자 변경 및 이미지 변경을 위한 ajax

$("#recommendVal").on("click", function(){

var userKey = $("#userKey").val();

var boardNum = $("#boardNum").val();

var recommendVal = $(this).attr("data-val");

 

if (recommendVal === "like") {

$.ajax({

type: "POST",

url: "<c:url value='/increaseDBoardRecommendNum'/>",

data: {

userKey: userKey,

boardNum: boardNum,

recommendVal: recommendVal

},

success: function(response) {

console.log(response)

$("#recommendNum").val(response)

$("#resultRecommendNum").text($("#recommendNum").val()-$("#disRecommendNum").val())

$("#recommendVal").attr("data-val", "likeChecked");

$("#recommendVal").attr("src", "<c:url value='/resources/images/member/like.svg'/>");

},

error: function(error) {

console.error("추천 기능 에러:", error);

}

})

} else (

alert("좋아요는 1일 1회만 가능합니다.")

)

})

 

 

//비추천을 위한 이미지 클릭 시 추천 숫자 변경 및 이미지 변경을 위한 ajax

$("#disrecommendVal").on("click", function(){

var userKey = $("#userKey").val();

var boardNum = $("#boardNum").val();

var disrecommendVal = $(this).attr("data-val");

 

if (disrecommendVal === "dislike") {

$.ajax({

type: "POST",

url: "<c:url value='/decreaseDBoardRecommendNum'/>",

data: {

userKey: userKey,

boardNum: boardNum,

disrecommendVal: disrecommendVal

},

success: function(response) {

$("#disRecommendNum").val(response)

$("#resultRecommendNum").text($("#recommendNum").val()-$("#disRecommendNum").val())

$("#disrecommendVal").attr("data-val", "dislikeChecked");

$("#disrecommendVal").attr("src", "<c:url value='/resources/images/member/dislike.svg'/>");

},

error: function(error) {

console.error("비추천 기능 에러:", error);

}

})

} else (

alert("싫어요는 1일 1회만 가능합니다.")

)

})

 

</script>

 

 

<!-- 부트 스트랩 -->

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

<script type="text/javascript">

var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))

var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {

return new bootstrap.Popover(popoverTriggerEl)

})

</script>

</body>

</html>

 

게시판에 들어가면

A. 컨트롤러

1. 유저 임시 아이디 쿠키 찾기

- 임시 아이디가 없을 경우 생성

 

2. 유저 임시 아이디와 게시판 번호, 좋아요/싫어요 여부를 조합한 Key를 통해 쿠키 찾기

- 쿠키가 있을 경우, value값을 저장하고 jsp로 전송

 

B. JSP

1. 유저 임시 아이디 | 좋아요/싫어요 여부를 hidden으로 가져옴

 

2. 좋아요/싫어요가 있을 경우, 좋아요/싫어요를 누른 상태로 이미지와 data-val을 변경

 

3. 좋아요/싫어요가 없을 경우

- 좋아요/싫어요를 누르면 ajax 발동

 

C. 컨트롤러

1. 게시판 번호를 통해 dto 불러오기

2. 불러온 dto에서 일단 return할 좋아요/싫어요 숫자를 저장

// - 이 부분은 jsp에서 코드 처리를 통해 필요없어진 코드가 일부 존재

3. jsp로부터 받은 유저 임시 아이디 | 게시판 번호 | 좋아요/싫어요 여부를 통해 쿠키 Key 생성

4. 좋아요 상태일 경우, 추천수 증가 + 쿠키에 key와 좋아요 여부를 저장

//

5. jsp에 return

 

D. jsp

1. return 받은 숫자로 추천수 변경

2. 좋아요/싫어요 이미지 + data-val 변경