본문 바로가기
Develop/JSP

페이지 댓글 구현하기

by ys2ys2 2024. 10. 3.

DB 부분은 어느정도 끝나서 (최종이라고 올렸지만 수정할게 아직 더 남았다..)

'여행톡' 이라는 부분을 구현해 보려고 한다.

 

- 현재까지 진행 상황 -

 

페이지 상단
상세정보 부분
구글 맵 API 부분

 

inputApi를 통해 테이블에 저장된 값으로

제목 : hotplace 테이블의 title 값 출력

장소 : addr1 값 출력

이미지 : firstimage 값 출력

상세정보 : overview 값 출력

 

이렇게 해서 페이지를 채워주게 했다. DB는 여행톡 개발 끝나면 사진, 소제목 더 추가해야 한다.

(사용하고 있는 공공데이터에 더 많은 정보들이 제공되고 있어서 그것도 더 추가해야 함!)

 

다음은 여행톡 부분!

 

여행톡 옆에 0 부분은 댓글 갯수만큼 카운트,

입력 폼은

로그인 X → readonly 상태로 클릭 시 알람 창과 함께 로그인 페이지로 이동

로그인 O → 되어있으면 작성하기 버튼이 보이면서 댓글 작성 가능

 

댓글 작성 → 로그인 한 닉네임으로 작성자 표시, 댓글 작성 시간 표시

댓글 수정,삭제 → 로그인 한 email을 기준으로 작성된 댓글의 email과 같으면 삭제하기, 수정하기 버튼 표시

 

정도로 생각하고 일단 시작!

 

일단 로그인 하면 로그인한 email, nickname값이 핫플 페이지로 넘어오게 해야 한다.

 

회원가입, 로그인, 마이페이지 부분을 맡아 준 예슬이가

이메일 회원가입 부분을 벌써 다 만들어놔서 정말 편하게 작업했다!

(덕분에 진행이 바로바로 됐어요! 무한 감사!!🙇‍♂️)

 

일단 여행톡 테스트를 위한 계정 2개를 만들었다.

(인증번호가 실제 사용하는 이메일로 오고 그 값으로 인증이 되는게 신기했다.. 이거 어케하는거야?)

이메일 인증

 

같은 방법으로 이메일로 계정 2개 만들어놓고 테스트 시작!

 

일단 로그인을 하면 메인페이지에 로그인 값이 넘어가는지 확인해보려고 했다.

 

login.jsp → loginProcess.jsp 이렇게 진행됐고

로그인 성공 시 이메일로 회원 정보를 조회하게 만들어져 있었다. 이걸 전역적으로 사용하려면 세션을 이용하라고 했다.

 

여기서 ❓물음표!❓
세션은 어떻게 쓰는거고 세션에 저장하는 방법?

세션에 저장하면 모든 JSP 페이지에서 사용할 수 있을까? 따로 저장한 값 불러오는 부분들을 추가해줘야 쓸 수 있을까? 싶었다.

메인 페이지 뿐만 아니라 각 게시판에서도 로그인된 값들을 사용해서 해야 할 게 많았기 때문에 어떻게 처리되는지 궁금했다.

 

이것저것 찾아본 결과 세션에 저장해두면 모든 JSP 페이지에서 쓸 수 있고

세션 종료 및 데이터 삭제를 통해서 저장된 세션을 삭제할 수 있었다. (로그아웃)

 

<!-- 세션에 이메일과 닉네임 저장 -->
<c:set var="memberEmail" value="${member.m_email}" scope="session" />
<c:set var="memberNickname" value="${member.m_nickname}" scope="session" />

 

memberEmail, memberNickname 이라는 ,

member.m_email, member.m_nickname 이라는
으로 저장해두고

세션에 저장된 데이터들을 다른 JSP 페이지에서 가져올 때는 sessionScope를 사용하면 된다고 했다.

<div class="test">
	${sessionScope.memberNickname}님 환영합니다!
	<form action="${pageContext.request.contextPath}/Login/logout.jsp" method="post">
		<button type="submit">로그아웃</button>
	</form>         			
</div>

 

sessionScope로 memberNickname의 값을 불러오게 했다. 결과는?

 

환영해요 칩자바!

 

이렇게 mainpage.jsp에서도 로그인 후 저장된 nickName이 잘 나오고 있었다! 이걸 그대로 핫플 페이지로 심기!

 

 

일단 로그인이 되어있지 않으면 readonly로 막아놓고 입력 폼을 누르면 알람과 함께 로그인 페이지로 이동하게 했다.

로그인 X → 입력 폼 클릭시 알람 + 로그인 페이지 이동

 

<div class="comment-form">
<%-- 사용자 정보가 세션에 있는지 확인 --%>
<c:choose>
    <c:when test="${not empty sessionScope.memberNickname}">
        <!-- 로그인된 사용자가 댓글 작성 가능 -->
        <textarea id="commentText" placeholder="소중한 댓글을 남겨주세요."></textarea>
        <div class="form-actions">
            <button class="login-button" id="submitButton">작성하기</button>
        </div>
    </c:when>
    <c:otherwise>
        <!-- 로그인되지 않은 경우 -->
        <a href="${pageContext.request.contextPath}/Login/login.jsp" onclick="alert('로그인 해 주시길 바랍니다!');">
        <textarea id="commentText" placeholder="로그인 후 소중한 댓글을 남겨주세요." readonly onclick="redirectToLogin()"></textarea>
        </a>
    </c:otherwise>
</c:choose>

</div>

 

일단 조건문을 써서 sessionScope로 memberNickname이 있으면 로그인 되었다고 생각하고
댓글을 작성할 수 있게 버튼과 입력 폼을 열어줬다.

없으면? login.jsp로 이동시키기! 그리고 readonly로 입력 폼 막아두기.

 

칩자바 로그인 완료!

 

이렇게 memberNickname 값이 들어오면 댓글 폼과 작성하기 버튼이 보여진다.

 

이제 댓글 작성해서 DB에 보내기!

Talk라는 테이블에

talk_idx, talk_nickname, talk_email, talk_text, talk_created_at, talk_updated_at 이렇게 속성을 넣어줬다.

(원래 처음에 t_idx, t_nickname 이렇게 하다가 DAO 짤 때 getTNickname 이렇게 2개 연속 대문자 나오면 오류떠서 바꿨다..)

 

DTO 만들어주고 그 다음은

 

🛑댓글 작성하기!

String sql = "INSERT INTO talk (talk_nickname, talk_email, talk_text) VALUES (?, ?, ?)";

 

간단하게 닉네임, 이메일, 댓글 내용(텍스트)를 넣어줬다.

talk_idx는 auto_increment고

talk_created_at, talk_updated_at도 자동으로 들어가서 3개 값만 넣어줬다.

 

댓글 가져오기!

그리고 DB에 저장된 리스트 가져오는 부분도 만들었다.

String sql = "SELECT talk_idx, talk_nickname, talk_email, talk_text, talk_created_at, talk_updated_at FROM talk ORDER BY talk_created_at DESC";

 

일단 다 가져오고 created_at 순으로 정렬했다.

talk_idx로는 댓글 삭제, 수정을 하려고 생각했고

talk_nickname으로는 작성자 닉네임 : 댓글 내용

talk_email로 db에 저장된 email = 세션에 저장된 email이면 삭제, 수정 버튼이 보이게 하려고 했다.

talk_text = 댓글 내용

talk_created_at = 댓글 작성시간 화면에 나오게 하기

talk_updated_at = 댓글 수정하면 수정시간으로 바뀌게 하기

 

🛑댓글 삭제!

    public int deleteTalk(int talkIdx) {
        int result = 0;
        String sql = "DELETE FROM talk WHERE talk_idx = ?";
        
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, talkIdx); // 삭제할 댓글의 ID 설정
            result = pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close();
        }
        
        return result;
    }

 

talk-id값 찾기

댓글 div 마다 data-talk-id값을 주고

const talkIdx = this.getAttribute("data-talk-id");

js로 data-talk-id값을 가져온 후 deleteTalk.jsp로 보낸다!

그 후 data-talk-id에 해당하는 talk_idx를 잡아서

String talkIdxStr = request.getParameter("talkIdx");
    
    if (talkIdxStr != null) {
        try {
            int talkIdx = Integer.parseInt(talkIdxStr); // `talkIdx`를 정수형으로 변환

            TalkDAO talkDAO = new TalkDAO(); // TalkDAO 객체 생성
            int result = talkDAO.deleteTalk(talkIdx); // 댓글 삭제 실행
            
            if (result == 1) {
                out.print("댓글이 삭제되었습니다.");
            } else {
                out.print("댓글 삭제에 실패하였습니다.");
            }
        } catch (Exception e) {
            e.printStackTrace();
            out.print("댓글 삭제 중 오류가 발생하였습니다.");
        }
    } else {
        out.print("잘못된 요청입니다.");
    }

talkDAO로 고고!

DAO에서는

String sql = "DELETE FROM talk WHERE talk_idx = ?";

 

이렇게 talk_idx의 매개변수를 받아서 

 pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, talkIdx); // 삭제할 댓글의 ID 설정
            result = pstmt.executeUpdate();

 

이렇게 talk_idx 값으로 삭제하게 구현했다.

 

 

🛑댓글 수정! 

댓글 수정도 같게 idx로 찾아서 updatetext하기

// 댓글 수정
public int updateTalk(int talkIdx, String updatedText) {
    int result = 0;
    String sql = " UPDATE talk SET talk_text = ? WHERE talk_idx = ? ";

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, updatedText);	// 수정할 댓글 내용 설정
        pstmt.setInt(2, talkIdx);		// 수정할 댓글의 ID 설정
        result = pstmt.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        close();
    }
    return result;
}

 

작성하기 버튼의 id="submitButton"을 통해서 js를 짜줬다.

댓글 작성하고 버튼 누르면 submitTalk.jsp로 넘어가게 하기!

입력한 텍스트 값 확인하고 세션 닉네임, 이메일 가져오기

<%
    // 댓글 내용 가져오기
    String talkText = request.getParameter("talkText"); // talkText로 수정
    String talkNickname = (String) session.getAttribute("memberNickname"); // 세션에서 닉네임 가져오기
    String talkEmail = (String) session.getAttribute("memberEmail"); // 세션에서 이메일 가져오기


    // TalkDTO 객체 생성
    TalkDTO talk = new TalkDTO();
    talk.setTalkNickname(talkNickname);  // 세션에서 가져온 닉네임
    talk.setTalkEmail(talkEmail);        // 세션에서 가져온 이메일
    talk.setTalkText(talkText);          // 입력된 댓글 내용

    // TalkDAO 객체 생성 및 댓글 저장
    TalkDAO talkDAO = new TalkDAO();
    int result = talkDAO.insertTalk(talk);

    if (result > 0) {
        out.print("성공~");
    } else {
        out.print("실패!");
    }
%>

 

댓글 등록하면 window.location.reload();로 새로고침 하게 추가!

댓글 등록할때 닉네임도 저장해서 화면에 저장된 닉네임으로 댓글이 보이게 했다.

 

댓글 작성!

 

댓글 작성하고 확인을 위해 로그인한 이메일, DB에 저장된 이메일도 같이 출력했다.

<c:out value="로그인한 이메일: ${sessionScope.memberEmail}"/><br>
<c:out value="DB에 저장된 이메일: ${talk.talkEmail}"/>

 

그리고 talkIdx 값을 비교해서 삭제하기, 수정을 하게 했고 이 버튼들이 보이는건

세션에 저장된 이메일 = DB에 저장된 이메일 상태에만 가능하게 했다.

<div class="comment-actions">
    <c:if test="${sessionScope.memberEmail == talk.talkEmail}">
        <button class="delbtn" data-talk-id="${talk.talkIdx}">삭제하기</button>
        <button class="editbtn" data-talk-id="${talk.talkIdx}">수정하기</button>
    </c:if>
    <button class="cancelbtn" data-talk-id="${talk.talkIdx}" style="display:none;">취소하기</button>
    <button class="savebtn" data-talk-id="${talk.talkIdx}" style="display:none;">저장하기</button> 
</div>

 

삭제하기, 수정하기

 

이렇게 세션에 저장된 로그인한 이메일과 DB에 저장된 이메일이 같아야지만 삭제하기, 수정하기 버튼이 보이게 했다.

ja~@gmail.com이 로그인했지만 test@example.com의 이메일로 쓴 댓글은 삭제, 수정이 불가능하다.

 

 

일단 이렇게 여행톡 부분도 어느정도 마무리!

다음엔 공공데이터 API JSP에 적용하기, DB 저장하기 (추가) 편을 정리해야 한다..

할게 진~~~~~~~~~짜 많다!!!