1. 요구사항
- 매거진 게시글에는 댓글 리스트가 출력되어있다.
- 각 댓글의 오른쪽 끝단에는 '...' 으로 되어있는 버튼이 있는데 이걸 통해(Modal) 댓글을 삭제한다.
- 댓글을 삭제할 때 자기가 작성했던 댓글만 위의 버튼이 뜨게 한다. 또한 삭제도 이러한 과정이 이루어져야 한다.
2. 해결책
- 댓글 리스트에 있는 mbr_id와 로그인해서 가져온 mbr_id를 JSTL의 choose 기능을 이용해 서로 비교하여 분기에 따라 UI를 다르게 보이게 한다
3. 소스코드
3-1. SecurityConfig
http.authorizeRequests() //
.antMatchers("/admin").hasAuthority("ADMIN") // admin/** 경로는 권한 1(=ADMIN) 회원만 접속 가능
.antMatchers("/admin/**").hasAuthority("ADMIN") //
.antMatchers("/seller").hasAnyAuthority("ADMIN", "SELLER") // seller/** 경로는 권한 2(=seller) 회원만 접속 가능
.antMatchers("/seller/**").hasAnyAuthority("ADMIN", "SELLER") //
.antMatchers("/member").hasAnyAuthority("ADMIN", "MEMBER") // member/** 경로는 권한 3(=member) 회원만 접속 가능
.antMatchers("/member/**").hasAnyAuthority("ADMIN", "MEMBER") //
.antMatchers("/").permitAll()//
.antMatchers("/**").permitAll() //
.and().formLogin() //
.loginPage("/login").permitAll() //
.usernameParameter("mbr_id") // 로그인시 username을 mbr_id로 받아옴
.passwordParameter("mbr_pw") // 로그인시 password를 mbr_pw 받아옴
.defaultSuccessUrl("/").successHandler(customSuccessHandler) // 성공시 수행할 핸들러 로그인 전 페이지 반환
.failureHandler(customFailureHandler) // 실패 핸들러 login page에 오류 메세지 반환
.and()// oauth2userservice 타입으로 받아오기
.logout().logoutUrl("/logoutsuccess") // 로그아웃 처리
.logoutSuccessUrl("/main") // 로그아웃 성공 시 이동 페이지
.invalidateHttpSession(true) // 로그아웃 시 세션 제거
.deleteCookies("remember-me") // 자동 로그인 쿠키, Tomcat이 발급한 세션 유지 쿠키 삭제
.and().exceptionHandling() // 권한 없을 경우 접근거부
.accessDeniedPage("/denied") //
.and().oauth2Login().loginPage("/login") // 소셜로그인 처리
.userInfoEndpoint() //
.userService(principalOauth2UserService);
3-2. BoardController.java
// 매거진 게시글
@GetMapping("/board/magazine/{board_id}")
public ModelAndView magazineContent(@AuthenticationPrincipal MemberDetails memberDetails, MbrVO mbrVO, BoardVO boardVO,
MagazineCommentCriteria cri, ModelAndView mav) {
log.info("magazineContent...");
mav.setViewName("board/magazine_content");
// MemberDetails이 null일 때 ModelAndView에 addObject를 하면 예외처리가 된다
// 따라서 null일 때(로그인 상태가 아닐때) 해당 정보를 addObject 하지 않고 페이지를 출력한다
if (memberDetails != null) {
// 인증 회원 정보
MbrVO getMbr = securityService.getMbr(memberDetails.getUserID());
// 회원 정보 받아오기
mav.addObject("mbr", getMbr);
}
// 매거진 내용
mav.addObject("magazine_content", boardService.getMagazineContent(boardVO.getBoard_id()));
// 매거진 댓글 수 불러오기
mav.addObject("magazine_comment_cnt", boardService.getMagazineCommentCnt(boardVO.getBoard_id()));
// 페이징을 적용한 매거진 댓글 불러오기
mav.addObject("magazine_comment", boardService.getMagazineComment(mbrVO.getMbr_id(), boardVO.getBoard_id(), cri));
int total = boardService.getMagazineCommentTotal(cri);
log.info("total" + total);
mav.addObject("pageMaker", new MagazineCommentPageVO(cri, total));
return mav;
}
3-3. magazine_content.jsp (코드 간소화)
<!-- 댓글 리스트 -->
<c:choose>
<%-- 댓글 작성자가 로그인 한 회원과 일치하지 않을 때 --%>
<c:when test="${mbr.mbr_id ne comment.mbr_id}">
<button type="button" disabled>
...
</button>
</c:when>
<%-- 댓글 작성자가 로그인 한 회원과 일치 할 때 --%>
<c:otherwise>
<%-- 모달을 열기 위한 버튼 --%>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#mdal${comment.comment_id}">
...
</button>
<%-- 모달 영역 --%>
<div class="modal fade myModal" id="mdal${comment.comment_id}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">X</span></button>
</div>
<div class="modal-body">
<p class="lead" align="left">${comment.comment_content}</p>
</div>
<div class="modal-footer">
<div align="left">
<button type="button" data-rno="${comment.comment_id}">
삭제하기
</button>
<%-- 매거진 댓글 삭제 --%>
<script type="text/javascript">
$(document).ready(function (){
$('.cmnt_del').click(function(event){
event.preventDefault();
// FormData 객체 생성
var formData = new FormData();
// button의 data-rno 값을 가져온다
var cmntInfo = $(this).attr("data-rno");
console.log("cmntInfo: " + cmntInfo);
// formData에 해당 값을 append한다
formData.append("comment_id", cmntInfo);
console.log("formData: " + formData);
$.ajax({
type : 'DELETE',
url : $(this).attr("href"),
cache : false,
processData: false,
contentType: false,
data: formData,
success: function(result){
console.log(result);
$(location).attr('href', '${pageContext.request.contextPath}/board/magazine/${magazine_content.board_id}')
console.log("COMMENT_REMOVED!")
},
error:function(e){
console.log(e);
}
})
});
});
</script>
</div>
</div>
</div>
</div>
</div>
</c:otherwise>
</c:choose>
최근댓글