2021년 01월 04일

업데이트:


프로젝트 구성

20210104_01



게시글 상세조회 페이지

  • 게시글 한 행 아무데나 클릭하면 상세조회로 이동
    20210104_05

  • 상세조회 페이지
    20210104_06


Script 부분(noticeList.jsp)

<script>
    // 공지사항 상세보기 기능 (jquery를 통해 작업)
    
    
    // 한 행 내 아무곳이나 클릭 시 상세조회가 가능하게
    // 한 행은 tr로 이루어져있고 그 내부엔 td가 존재한다.
    // 어느 td를 선택해도 첫번째 td(게시글 번호)가 선택되도록 한다.
    $("#list-table td").on("click", function(){
        
        // this : 현재 클릭이 된 td 태그
        var noticeNo = $(this).parent().children().eq(0).text();
        //parent() : 부모
        //children() : 모든 자식들
        //eq(0) : 중에서 제일 첫번째 자식
        //text() : 의 내용(text)을 얻어옴
        
        //console.log(noticeNo);
        
        // 얻어온 공지사항 글 번호를 쿼리 스트링으로 작성하여 상세조회 요청
        location.href = "${contextPath}/notice/view.do?no=" + noticeNo;
        
        //location : 주소창과 관련된 객체
    });
</script>

NoticeController.java

// 공지사항 상세 조회 Controller *****************************
else if(command.equals("/view.do")) {
    errorMsg = "공지사항 상세 조회 과정에서 오류 발생";
    
    // 쿼리스트링으로 전달된 공지사항 번호를 int형으로 파싱하여 저장
    int noticeNo = Integer.parseInt(request.getParameter("no"));
    
    // 상세조회 비즈니스 로직 수행 결과 반환
    Notice notice = service.selectNotice(noticeNo);
    
    // 조회 결과에 따른 view 연결 처리
    if(notice != null) { // 조회 성공
        path = "/WEB-INF/views/notice/noticeView.jsp";
        request.setAttribute("notice", notice);
        view = request.getRequestDispatcher(path);
        view.forward(request, response);
    }else { // 조회 실패
        HttpSession session = request.getSession();
        session.setAttribute("swalIcon", "error");
        session.setAttribute("swalTitle", "공지사항 조회 실패");
        
        // referer : 이전 요청 주소
        response.sendRedirect(request.getHeader("referer"));
    }
}



NoticeService.java

/** 공지사항 상세 조회 Service
    * @param noticeNo
    * @return notice
    * @throws Exception
    */
public Notice selectNotice(int noticeNo) throws Exception{
    Connection conn = getConnection();
    
    Notice notice = dao.selectNotice(conn, noticeNo);
    
    // 공지사항 조회 성공 시 조회수 증가
    if(notice != null) {
        int result = dao.increaseReadCount(conn, noticeNo);
        
        // 트랜잭션 처리
        if(result > 0) {
            commit(conn);
            // 이미 조회된 notice에서 readCount 값을 1 wmdrk
            notice.setReadCount(notice.getReadCount() + 1);
        }else {
            rollback(conn);
        }
    }
    close(conn);
    return notice;
}



notice-query.xml

<!-- 공지사항 상세 조회 -->
<entry key="selectNotice">
SELECT NOTICE_TITLE, NOTICE_CONTENT, MEMBER_ID, READ_COUNT, NOTICE_CREATE_DT
FROM NOTICE
JOIN MEMBER ON(NOTICE_WRITER = MEMBER_NO)
WHERE NOTICE_NO = ?
AND NOTICE_FL = 'Y'
</entry>



NoticeDAO.java

/** 공지사항 상세 조회 DAO
    * @param conn
    * @param noticeNo
    * @return notice
    * @throws Exception
    */
public Notice selectNotice(Connection conn, int noticeNo) throws Exception {

    // 1) 결과 저장용 변수 선언
    Notice notice = null;
    
    // 2) SQL 구문 얻어오기
    String query = prop.getProperty("selectNotice");
    
    // 3) SQL 수행 후 결과를 notice에 저장
    try {
        pstmt = conn.prepareStatement(query);
        
        pstmt.setInt(1,  noticeNo);
        
        rset = pstmt.executeQuery();
        
        if(rset.next()) {
            notice = new Notice();
            notice.setNoticeTitle(rset.getString("NOTICE_TITLE"));
            notice.setNoticeContent(rset.getString("NOTICE_CONTENT"));
            notice.setMemberId(rset.getString("MEMBER_ID"));
            notice.setReadCount(rset.getInt("READ_COUNT"));
            notice.setNoticeCreateDate(rset.getDate("NOTICE_CREATE_DT"));
        }
    }finally {
        // 4) 사용한 JDBC 객체 반환
        close(rset);
        close(pstmt);
    }
    // 5) 결과 반환
    return notice;
}



조회수 증가(notice-query.xml)

<!-- 공지사항 상세 조회 -->
<entry key="selectNotice">
SELECT NOTICE_TITLE, NOTICE_CONTENT, MEMBER_ID, READ_COUNT, NOTICE_CREATE_DT
FROM NOTICE
JOIN MEMBER ON(NOTICE_WRITER = MEMBER_NO)
WHERE NOTICE_NO = ?
AND NOTICE_FL = 'Y'
</entry>



조회수 증가(NoticeDAO.java)

/** 조회수 증가 DAO
    * @param conn
    * @param noticeNo
    * @return result
    * @throws Exception
    */
public int increaseReadCount(Connection conn, int noticeNo) throws Exception {
    int result = 0;
    
    String query = prop.getProperty("increaseReadCount");
    
    try {
        pstmt = conn.prepareStatement(query);
        pstmt.setInt(1, noticeNo);
        
        result = pstmt.executeUpdate();
    } finally {
        close(pstmt);
    }
    
    return result;
}



관리자 계정으로 로그인 시 글쓰기 버튼 보이기(noticeList.jsp)

  • 비회원, 일반회원 로그인 시
    • 비회원
      20210104_02

    • 일반회원
      20210104_04
  • 관리자 로그인 시
    20210104_03

    <%-- 로그인된 계정이 관리자 등급인 경우 --%>
<c:if test="${!empty loginMember && loginMember.memberGrade == 'A'}">
    <button type="button" class="btn btn-primary float-right" 
        id="insertBtn" onclick="location.href = 'insertForm.do';">
        글쓰기</button>
</c:if>



공지사항 게시글 작성 페이지

  • 글쓰기 버튼 클릭 시 게시글 작성 페이지로 이동
    20210104_07

NoticeController.java

// 공지사항 작성 화면 전환 Controller ************************************
else if(command.equals("/insertForm.do")){
    path = "/WEB-INF/views/notice/noticeInsert.jsp";
    view = request.getRequestDispatcher(path);
    view.forward(request, response);
}



noticeInsert.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항</title>
<style>
	#notice-area{ height: 700px;}
</style>
</head>
<body>
  <jsp:include page="../common/header.jsp"></jsp:include>
	<div class="container my-5">
			<h3>공지사항 등록</h3>
		      <hr>
		      <div class="bg-white rounded shadow-sm container py-3" id="notice-area">
		        <form method="POST" action="insert.do" role="form" onsubmit="return noticeValidate();">
		          <div class="form-inline mb-2">
		            <div class="input-group">
		              <label class="input-group-addon mr-3">제목</label>
		              <input type="text" class="form-control" id="noticeTitle" name="noticeTitle" size="70">
		            </div>
		          </div>
		
		          <div class="form-inline mb-2">
		            <div class="input-group">
		              <label class="input-group-addon mr-3">작성자</label>
		              <h5 class="my-0">${loginMember.memberId }</h5>
		            </div>
		          </div>
		
		
		          <div class="form-inline mb-2">
		            <div class="input-group">
		              <label class="input-group-addon mr-3">작성일</label>
		              <h5 class="my-0" id="today"></h5>
		            </div>
		          </div>
		
		          <hr>
		
		          <div class="form-group">
		            <div><label for="content">내용</label> </div>
		            <textarea class="form-control" id="noticeContent" name="noticeContent" rows="15" style="resize: none;"></textarea>
		          </div>
		
		
		        <hr class="mb-4">
		
		        <div class="text-center">
					<button type="submit" class="btn btn-primary">등록</button>
					<a href="list" class="btn btn-primary">목록으로</a>
				</div>
		        
		        </form>
		      </div>

	</div>
	<jsp:include page="../common/footer.jsp"></jsp:include>
	
	<script>
    (function printToday(){
        // 오늘 날짜 출력 (작성일)
        
        var now = new Date(); // 현재 시간 
        var year = now.getFullYear(); // 2021
        var month = now.getMonth() + 1; // getMonth() : 0 ~ 11 중 하나가 반환, 0
        var date = now.getDate(); // 4(일)
        
        var str = year + "-"
              + (month < 10 ? "0" + month : month ) + "-" // 삼항연산자 이용. 1~9일 때는 01~09, 아닐 때는 10~12
              + (date < 10 ? "0" + date : date);
        
        $('#today').text(str);
     })();
		// 유효성 검사
		function noticeValidate(){
			if( $("#noticeTitle").val().trim().length == 0){
				alert("제목을 입력해 주세요.");
				$("#title").focus();
				return false;
			}
			
			if( $("#noticeContent").val().trim().length == 0){
				alert("내용을 입력해 주세요.");
				$("#content").focus();
				return false;
			}
		}
	</script>
</body>
</html>



공지사항 등록

NoticeController.java

// 공지사항 등록 Controller ************************************
else if(command.equals("/insert.do")){
    errorMsg = "공지사항 등록 과정에서 오류 발생";
    
    // 파라미터로 전달된 값 저장
    String noticeTitle = request.getParameter("noticeTitle");
    String noticeContent = request.getParameter("noticeContent");
    
    // 세션에서 회원 번호 얻어오기
    HttpSession session = request.getSession();
    int noticeWriter = ((Member)session.getAttribute("loginMember")).getMemberNo();
    
    // Map을 이용하여 데이터 전달(VO 대신 사용하는 경우가 많음)
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("noticeTitle", noticeTitle);
    map.put("noticeContent", noticeContent);
    map.put("noticeWriter", noticeWriter);
    
    // 공지사항 등록 비즈니스 로직 수행 후 결과 반환
    int result = service.insertNotice(map);
    
    if(result > 0) { // 삽입 성공 시
        // result에는 삽입된 공지사항 번호가 저장되어 있음.
        path = "view.do?no=" + result; // 쿼리스트링을 이용하여 상세조회 요청
        swalIcon = "success";
        swalTitle = "공지사항이 등록되었습니다.";
        
    } else { // 공지사항 등록 실패 시
        path = "list.do";
        swalIcon = "error";
        swalTitle = "공지사항 등록 실패";
    }
    
    session.setAttribute("swalIcon", swalIcon);
    session.setAttribute("swalTitle", swalTitle);
    
    response.sendRedirect(path);
}



NoticeService.java

/** 공지사항 등록 Service
    * @param map
    * @return result
    * @throws Exception
    */
public int insertNotice(Map<String, Object> map) throws Exception{
    
    Connection conn = getConnection();
    
    // 1. 작성될 글번호를 먼저 얻어오는 DAO 메소드 수행
    // 이유 1) 글 작성 성공 후 해당 글 상세 조회 페이지로 redirect 하기 위해 필요
    // 이유 2) 글 작성 + 파일 첨부 시 발생하는 시퀀스 번호 밀림 현상을 제거하기 위해
    int noticeNo = dao.selectNextNo(conn);
    
    int result = 0;
    
    if(noticeNo > 0) { // 다음 글번호를 얻어오는데 성공한 경우
        
        // 2. 실제 공지글 등록 DAO 메소드 수행
        
        // map에 얻어온 다음 글 번호를 세팅
        map.put("noticeNo", noticeNo);
    
        result = dao.insertNotice(conn, map);
        
        // 트랜잭션 처리
        if(result > 0) {
            commit(conn);
            // 삽입 성공 시 result에 작성한 글 번호를 대입
            result = noticeNo; // 글 번호가 최종적으로 반환됨
        }else {
            rollback(conn);
        }
    }
    close(conn);
    return result;
}



공지사항 등록 시 사용될 게시글 번호(NoticeDAO.java)

/** 공지사항 등록 시 사용될 번호 반환 DAO
    * @param conn
    * @return noticeNo
    * @throws Exception
    */
public int selectNextNo(Connection conn) throws Exception {
    int noticeNo = 0;
    
    String query = prop.getProperty("selectNextNo");
    
    try {
        stmt = conn.createStatement();
        rset = stmt.executeQuery(query);
        if(rset.next()) {
            noticeNo = rset.getInt(1);
        }
    } finally {
        close(rset);
        close(stmt);
    }
    return noticeNo;
}



공지사항 등록 시 사용될 query(notice-query.xml)

<!-- 다음 번호 얻어오기 -->
<entry key="selectNextNo">
SELECT SEQ_NNO.NEXTVAL FROM DUAL
</entry>



NoticeService.java

/** 공지사항 등록 Service
    * @param map
    * @return result
    * @throws Exception
    */
public int insertNotice(Map<String, Object> map) throws Exception{
    
    Connection conn = getConnection();
    
    // 1. 작성될 글번호를 먼저 얻어오는 DAO 메소드 수행
    // 이유 1) 글 작성 성공 후 해당 글 상세 조회 페이지로 redirect 하기 위해 필요
    // 이유 2) 글 작성 + 파일 첨부 시 발생하는 시퀀스 번호 밀림 현상을 제거하기 위해
    int noticeNo = dao.selectNextNo(conn);
    
    int result = 0;
    
    if(noticeNo > 0) { // 다음 글번호를 얻어오는데 성공한 경우
        
        // 2. 실제 공지글 등록 DAO 메소드 수행
        
        // map에 얻어온 다음 글 번호를 세팅
        map.put("noticeNo", noticeNo);
        result = dao.insertNotice(conn, map);
        
        // 트랜잭션 처리
        if(result > 0) {
            commit(conn);
            // 삽입 성공 시 result에 작성한 글 번호를 대입
            result = noticeNo; // 글 번호가 최종적으로 반환됨
        }else {
            rollback(conn);
        }
    }
    
    close(conn);
    
    return result;
}
	

공지사항 등록 시 사용될 게시글 번호(NoticeDAO.java)

/** 공지사항 등록 시 사용될 번호 반환 DAO
    * @param conn
    * @return noticeNo
    * @throws Exception
    */
public int selectNextNo(Connection conn) throws Exception {
    int noticeNo = 0;
    String query = prop.getProperty("selectNextNo");
    
    try {
        stmt = conn.createStatement();
        rset = stmt.executeQuery(query);
        if(rset.next()) {
            noticeNo = rset.getInt(1);
        }
    } finally {
        close(rset);
        close(stmt);
    }
    return noticeNo;
}



공지사항 등록(NoticeService.java)

/** 공지사항 등록 Service
    * @param map
    * @return result
    * @throws Exception
    */
public int insertNotice(Map<String, Object> map) throws Exception{
    
    Connection conn = getConnection();
    
    // 1. 작성될 글번호를 먼저 얻어오는 DAO 메소드 수행
    // 이유 1) 글 작성 성공 후 해당 글 상세 조회 페이지로 redirect 하기 위해 필요
    // 이유 2) 글 작성 + 파일 첨부 시 발생하는 시퀀스 번호 밀림 현상을 제거하기 위해
    int noticeNo = dao.selectNextNo(conn);
    
    int result = 0;
    
    if(noticeNo > 0) { // 다음 글번호를 얻어오는데 성공한 경우
        
        // 2. 실제 공지글 등록 DAO 메소드 수행
        
        // map에 얻어온 다음 글 번호를 세팅
        map.put("noticeNo", noticeNo);
        
        result = dao.insertNotice(conn, map);
        
        // 트랜잭션 처리
        if(result > 0) {
            commit(conn);
            // 삽입 성공 시 result에 작성한 글 번호를 대입
            result = noticeNo; // 글 번호가 최종적으로 반환됨
        }else {
            rollback(conn);
        }
    }
    close(conn);
    return result;
}



공지사항 등록(notice-query.xml)

<entry key="insertNotice">
INSERT INTO NOTICE(NOTICE_NO, NOTICE_TITLE, NOTICE_CONTENT, NOTICE_WRITER)
VALUES(?, ?, ?, ?)
</entry>



공지사항 등록(NoticeDAO.java)

/** 공지사항 등록 DAO
    * @param conn
    * @param map
    * @return result
    * @throws Exception
    */
public int insertNotice(Connection conn, Map<String, Object> map) throws Exception {
    int result = 0;
    String query = prop.getProperty("insertNotice");
    
    try {
        pstmt = conn.prepareStatement(query);
        
        pstmt.setInt(1, (int)map.get("noticeNo"));
        pstmt.setString(2, (String)map.get("noticeTitle"));
        pstmt.setString(3, (String)map.get("noticeContent"));
        pstmt.setInt(4, (int)map.get("noticeWriter"));
        
        result = pstmt.executeUpdate();
        
    } finally {
        close(pstmt);
    }
    return result;
}



크로스 사이트 스크립팅

크로스 사이트 스크립팅은 웹 애플리케이션에서 많이 나타나는 보안 취약점 중 하나로 웹 사이트 관리자가 아닌 사용자가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다.

  • 크로스 사이트 스크립팅 방지 미적용 시 게시글 제목, 내용에 html 태그를 사용할 수 있다.
    20210104_08

NoticeService.java

private String replaceParameter(String param) {
    String result = param;
    
    if(result != null) {
        result = result.replaceAll("&", "&amp;");
        result = result.replaceAll("<", "&lt;");
        result = result.replaceAll(">", "&gt;");
        result = result.replaceAll("\"", "&quot;");
    }
    
    return result;
}

사용

  • 게시글을 작성, 수정할 수 있는 Service 메소드 내에 작성한다.
map.put("noticeTitle", replaceParameter((String)map.get("noticeTitle")));
map.put("noticeContent", replaceParameter((String)map.get("noticeContent")));



개행문자 변경 처리

textarea 박스 내에서 개행문자(엔터)는 \r\n 이지만 상세 조회에서 사용되는 div 태그의 개행문자는 <br>이기 때문에 변경이 필요하다.

  • 개행문자 변경 처리 미적용 시
    20210104_09


NoticeService.java

// 공지사항 등록 Service 내 dao로 전달하기 전에 작성
map.put("noticeContent", 
            ((String)map.get("noticeContent")).replaceAll("\r\n", "<br>") );



상세 페이지에서 관리자 계정에서만 ‘수정’, ‘삭제’ 버튼 보이기

  • 비회원, 일반회원 로그인 시
    • 비회원
      20210104_12
    • 일반회원
      20210104_13
  • 관리자 로그인 시
    20210104_11


noticeView.jsp

<%-- 로그인된 회원이 해당 글의 작성자인 경우 --%>
<c:if test="${!empty loginMember && (loginMember.memberId == notice.memberId)}">
    <button class="btn btn-primary float-right" id="deleteBtn">삭제</button>
    <a href="updateForm.do?no=${param.no}" class="btn btn-primary float-right ml-1 mr-1">수정</a>
    <%-- request 파라미터  no가 존재하고 있음 --%>>
</c:if>



공지사항 수정

수정 화면 출력(NoticeController.java)

  • 수정을 눌렀을 때 아래와 같이 기존의 게시글 내용들이 보여야한다.
    20210104_14
// 공지사항 수정 화면 출력용 Controller
else if(command.equals("/updateForm.do")) {
    errorMsg = "공지사항 수정 화면 전환 과정에서 오류 발생";
    
    int noticeNo = Integer.parseInt(request.getParameter("no"));
    
    Notice notice = service.updateView(noticeNo);
    
    if(notice != null) {
        path ="/WEB-INF/views/notice/noticeUpdate.jsp";
        request.setAttribute("notice", notice);
        view = request.getRequestDispatcher(path);
        view.forward(request, response);
    }else {
        request.getSession().setAttribute("swalIcon", "error");
        request.getSession().setAttribute("swalText", "공지사항 수정을 위한 조회 실패");
        
        response.sendRedirect("view.do?no=" + noticeNo);
    }
}



수정 화면 출력(NoticeService.java)

	/** 공지사항 수정 화면 Service
	 * @param noticeNo
	 * @return notice
	 * @throws Exception
	 */
	public Notice updateView(int noticeNo) throws Exception{
		Connection conn = getConnection();
		
		// 공지사항 상세조회 DAO 메소드 호출
		Notice notice = dao.selectNotice(conn, noticeNo);
		
		// textarea에 출력하기 위해 개행문자 변경
		if(notice != null) {
			notice.setNoticeContent(notice.getNoticeContent().replaceAll("<br>", "\r\n"));
		}
		close(conn);
		return notice;
	}



수정 화면 출력(notice-query.xml)

<!-- 공지사항 상세 조회 --> (재사용)
<entry key="selectNotice">
SELECT NOTICE_TITLE, NOTICE_CONTENT, MEMBER_ID, READ_COUNT, NOTICE_CREATE_DT
FROM NOTICE
JOIN MEMBER ON(NOTICE_WRITER = MEMBER_NO)
WHERE NOTICE_NO = ?
AND NOTICE_FL = 'Y'
</entry>



수정 화면 출력(NoticeDAO.java)

/** 공지사항 상세 조회 DAO (재사용)
    * @param conn
    * @param noticeNo
    * @return notice
    * @throws Exception
    */
public Notice selectNotice(Connection conn, int noticeNo) throws Exception {

    // 1) 결과 저장용 변수 선언
    Notice notice = null;
    
    // 2) SQL 구문 얻어오기
    String query = prop.getProperty("selectNotice");
    
    // 3) SQL 수행 후 결과를 notice에 저장
    try {
        pstmt = conn.prepareStatement(query);
        
        pstmt.setInt(1,  noticeNo);
        
        rset = pstmt.executeQuery();
        
        if(rset.next()) {
            notice = new Notice();
            notice.setNoticeTitle(rset.getString("NOTICE_TITLE"));
            notice.setNoticeContent(rset.getString("NOTICE_CONTENT"));
            notice.setMemberId(rset.getString("MEMBER_ID"));
            notice.setReadCount(rset.getInt("READ_COUNT"));
            notice.setNoticeCreateDate(rset.getDate("NOTICE_CREATE_DT"));
        }
    }finally {
        // 4) 사용한 JDBC 객체 반환
        close(rset);
        close(pstmt);
    }
    
    // 5) 결과 반환
    return notice;
}



noticeUpdate.jsp

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항</title>
<style>
	#notice-area{ margin-bottom:200px;}
	#notice-content{ padding-bottom:150px;}
</style>
</head>
<body>
	<jsp:include page="../common/header.jsp"></jsp:include>

	<div class="container my-5">

		<h3>공지사항 수정</h3>
	      <hr>
	      <div class="bg-white rounded shadow-sm container py-3">
	        <form method="POST" action="update.do?no=${param.no }" role="form" onsubmit="return noticeValidate();">
	        
	        
	          <div class="form-inline mb-2">
	            <div class="input-group">
	              <label class="input-group-addon mr-3">제목</label>
	              <input type="text" class="form-control" id="noticeTitle" name="noticeTitle" size="70" value="${notice.noticeTitle }">
	            </div>
	          </div>
	
	          <div class="form-inline mb-2">
	            <div class="input-group">
	              <label class="input-group-addon mr-3">작성자</label>
	              <h5 class="my-0" id="writer">${notice.memberId }</h5>
	            </div>
	          </div>
	
	
	          <div class="form-inline mb-2">
	            <div class="input-group">
	              <label class="input-group-addon mr-3">작성일</label>
	              <h5 class="my-0" id="today">${notice.noticeCreateDate}</h5>
	            </div>
	          </div>
	
	          <hr>
	
	          <div class="form-group">
	            <div><label for="content">내용</label> </div>
	            <textarea class="form-control" id="noticeContent" name="noticeContent" rows="10" 
	            style="resize: none;">${notice.noticeContent }</textarea>
	          </div>
	
	
	        <hr class="mb-4">
	
       	<div class="text-center">
					<button type="submit" class="btn btn-primary">수정</button>
					<a href="view.do?no=${param.no }" class="btn btn-primary">취소</a>
				</div>
	        
      </form>
     </div>

	</div>
	<jsp:include page="../common/footer.jsp"></jsp:include>
	
	
	<script>
	// 유효성 검사
	function noticeValidate(){
		if( $("#noticeTitle").val().trim().length == 0){
			alert("제목을 입력해 주세요.");
			$("#title").focus();
			return false;
		}
		
		if( $("#noticeContent").val().trim().length == 0){
			alert("내용을 입력해 주세요.");
			$("#content").focus();
			return false;
		}
	}
	</script>
</body>
</html>



공지사항 수정

NoticeController.java

// 공지사항 수정 Controller
else if(command.equals("/update.do")) {
    errorMsg = "공지사항 수정이 실패했습니다.";
    
    // 파라미터 얻어오기
    int noticeNo = Integer.parseInt(request.getParameter("no"));
    String noticeTitle = request.getParameter("noticeTitle");
    String noticeContent = request.getParameter("noticeContent");
    
    
    // 비즈니스 로직 수행
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("noticeNo", noticeNo);
    map.put("noticeTitle", noticeTitle);
    map.put("noticeContent", noticeContent);
    
    int result = service.updateNotice(map);
    
    
    // 로직 수행 성공 시 "공지사항이 수정되었습니다." swal 출력
    if(result > 0) {
        swalIcon = "success";
        swalTitle = "공지사항이 수정되었습니다.";
    }
    // 로직 수행 실패 시 "공지사항이 수정 실패" swal 출력
    else {
        swalIcon = "error";
        swalTitle = "공지사항 수정이 실패했습니다.";
    }
    
    request.getSession().setAttribute("swalIcon", swalIcon);
    request.getSession().setAttribute("swalTitle", swalTitle);
    // 수정된 공지사항 상세조회로 redirect
    response.sendRedirect("view.do?no="+ noticeNo);
}



NoticeService.java

/** 공지사항 수정 등록 Service
    * @param map
    * @return result
    * @throws Exception
    */
public int updateNotice(Map<String, Object> map) throws Exception{
    int result = 0;
    
    Connection conn = getConnection();
    
    
    // 크로스 사이트 스크립팅 방지 처리
    map.put("noticeTitle", replaceParameter((String)map.get("noticeTitle")));
    map.put("noticeContent", replaceParameter((String)map.get("noticeContent")));
    /*
        * 생성자 사용시
        * notice.setNoticeTitle(replaceParameter(notice.getNoticeTitie()));
        * notice.setNoticeContent(replaceParameter(notice.getNoticeContent()));
        */
    
    
    // 개행문자 변경 처리
    map.put("noticeContent", 
                ((String)map.get("noticeContent")).replaceAll("\r\n", "<br>") );
    /* 개행문자 변경 처리
        * 생성자 이용시
        * 
        * notice.setNoticeContent( notice.getNoticeContent().replaceAll("\r\n", "<br>"));
        */
    
    result = dao.updateNotice(conn, map);
    if(result > 0) {
        commit(conn);
    }else {
        rollback(conn);
    }
    
    
    close(conn);
    
    return result;
}



notice-query.xml

<entry key="updateNotice">
UPDATE NOTICE SET
NOTICE_TITLE = ?,
NOTICE_CONTENT = ?
WHERE NOTICE_NO = ?
</entry>



NoticeDAO.java

public int updateNotice(Connection conn, Map<String, Object> map) throws Exception {
    int result = 0;
    
    String query = prop.getProperty("updateNotice");
    
    try {
        pstmt = conn.prepareStatement(query);
        pstmt.setString(1, (String)map.get("noticeTitle"));
        pstmt.setString(2, (String)map.get("noticeContent"));
        pstmt.setInt(3, (int)map.get("noticeNo"));

        result = pstmt.executeUpdate();
        
        
        
    } finally {
        close(pstmt);
    }
    return result;
}



게시글 삭제

팝업창

20210104_15

  • noticeView.jsp
<script>
    $("#deleteBtn").on("click", function(){
        if(confirm("정말 삭제하시겠습니까?")){
            location.href = "delete.do?no=${param.no}";
        }
    });
        
</script>



NoticeController.java

// 공지사항 삭제 Controller ***************************
else if(command.equals("/delete.do")) {
    errorMsg = "공지사항 삭제 과정에서 오류 발생";
    
    int noticeNo = Integer.parseInt(request.getParameter("no"));
    
    // 비즈니스 로직 수행
    int result = service.updateNoticeFl(noticeNo);
    
    if(result > 0) {
        swalIcon = "success";
        swalTitle = "공지사항이 삭제되었습니다.";
        path = "list.do";
    } else {
        swalIcon = "error";
        swalTitle = "공지사항이 삭제 실패.";
        path = request.getHeader("referer"); // 요청이 왔던 이전 주소
        
    }
    
    request.getSession().setAttribute("swalIcon", swalIcon);
    request.getSession().setAttribute("swalTitle", swalTitle);
    
    response.sendRedirect(path);
}



NoticeService.java

public int updateNoticeFl(int noticeNo) throws Exception {
    Connection conn = getConnection();
    
    int result = dao.updateNoticeFl(conn, noticeNo);
    
    if(result > 0) commit(conn);
    else rollback(conn);
    
    close(conn);
    
    return result;
}



notice-query.xml

<entry key="updateNoticeFl">
UPDATE NOTICE SET 
NOTICE_FL = 'N'
WHERE NOTICE_NO = ?
</entry>
</properties>



NoticeDAO.java

	public int updateNoticeFl(Connection conn, int noticeNo) throws Exception {
		
		int result = 0;
		
		String query = prop.getProperty("updateNoticeFl");
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, noticeNo);
			
			result = pstmt.executeUpdate();

		} finally {
			close(pstmt);
		}
		return result;
	}



삭제 시 DB NOTICE 테이블 NOTICE_FL 컬럼 값이 변경된다.
20210104_16

댓글남기기