✿∘˚˳°∘°

57일차 : mvc2WebProject - 4 본문

국비수업/Server

57일차 : mvc2WebProject - 4

_HYE_ 2023. 2. 19. 20:35

20230217

1. 공지사항 전체리스트보기(+페이징처리)

공지사항 메뉴를 클릭하면 이동할 Servlet

package kr.or.iei.notice.cotroller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.or.iei.notice.model.service.NoticeService;
import kr.or.iei.notice.model.vo.NoticePageData;

/**
 * Servlet implementation class NoticeListServlet
 */
@WebServlet(name = "NoticeList", urlPatterns = { "/noticeList.do" })
public class NoticeListServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public NoticeListServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1. 인코딩
		request.setCharacterEncoding("utf-8");
		//2. 값추출
		int reqPage = Integer.parseInt(request.getParameter("reqPage"));
		//3. 비즈니스로직
		NoticeService service = new NoticeService();
		NoticePageData npd = service.selectNoticeList(reqPage);
		//4. 결과처리
		RequestDispatcher view = request.getRequestDispatcher("/WEB-INF/views/notice/noticeList.jsp");
		request.setAttribute("list", npd.getList());
		request.setAttribute("pageNavi", npd.getPageNavi());
		request.setAttribute("start", npd.getStart());
		view.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

Service (여기서 페이징 처리를 해줄것)

	public NoticePageData selectNoticeList(int reqPage) {
		Connection conn = JDBCTemplate.getConnection();
		//공지사항 페이징처리
		//1. 한 페이지당 게시물 수 지정 -> 10개
		int numPerPage = 10;
		//요청페이지(reqPage)가 1페이지이면 -> 최신글 1~10(정렬기준)
		//요청페이지(reqPage)가 2페이지이면 -> 최신글 11~20
		//요청페이지(reqPage)가 3페이지면 -> 최신글 21~30
		//reqPage == 4 -> 31~40;
		int end = numPerPage*reqPage;
		int start = end - numPerPage + 1;
	
		ArrayList<Notice> list = dao.selectNoticeList(conn, start, end);
		//페이징제작 시작
		//전체페이지수를 계산 -> 총게시물 수를 조회
		int totalCount = dao.selectNoticeCount(conn);
		//전체 페이지수를 계산
		int totalPage = 0;
		if(totalCount%numPerPage == 0) {
			totalPage = totalCount/numPerPage;
		}else {
			totalPage = (totalCount/numPerPage) + 1;
		}
		//네비게이션 사이즈 : 지정해줘야 할 값 / 총페이지가 23페이지 일때 1~10페이지만 보여주고 다음버튼을 보여줄지 정하는것
		//아래 페이징버튼에 < 1 2 3 4 5 > 이렇게 만들어서 5페이지만 보여줄 것
		int pageNaviSize = 5;
		//페이지 네비게이션 시작번호
		//reqPage 1 ~ 5 : 1 2 3 4 5
		//reqPage 6 ~ 10 : 6 7 8 9 10
		//reqPage 11 ~ 15 : 11 12 13 14 15
		
		int pageNo = ((reqPage-1)/pageNaviSize)*pageNaviSize + 1;
		// ((reqPage-1)/5)*5 + 1
		// reqPage = 1~5 -> reqPage-1 = 0~4 
		// 0/5*5 + 1 = 1 -> 시작번호 1이 나옴 -> for문으로 증가해줄것
		
		//페이지 네비게이션 제작 시작
		String pageNavi = "<ul class='pagination circle-style'>";
		//이전버튼(<)
		if(pageNo != 1) {
			pageNavi += "<li>";
			pageNavi += "<a class='page-item' href='/noticeList.do?reqPage="+(pageNo-1)+"'>";
			pageNavi += "<span class='material-icons'>chevron_left</span>";
			pageNavi += "</a></li>";
		}
		//페이지 숫자(1 2 3 4 5)
		for(int i=0; i<pageNaviSize; i++) {
			if(pageNo == reqPage) {
				pageNavi += "<li>";
				pageNavi += "<a class='page-item active-page' href='/noticeList.do?reqPage="+(pageNo)+"'>";
				pageNavi += pageNo;
				pageNavi += "</a></li>";
			}else {
				pageNavi += "<li>";
				pageNavi += "<a class='page-item' href='/noticeList.do?reqPage="+(pageNo)+"'>";
				pageNavi += pageNo;
				pageNavi += "</a></li>";
			}
			pageNo++;
			//for문을 중간에 탈출해야하는 경우가 있음 - 페이지가 끝나면 그 이후페이지(없는페이지)는 출력X
			if(pageNo>totalPage) {
				break;
			}
		}
		//다음버튼
		if(pageNo <= totalPage) {
			pageNavi += "<li>";
			pageNavi += "<a class='page-item' href='/noticeList.do?reqPage="+(pageNo)+"'>";
			pageNavi += "<span class='material-icons'>chevron_right</span>";
			pageNavi += "</a></li>";
		}
		pageNavi += "</ul>";
		//return 해줘야 하는 데이터가 2가지 - ArrayList<Notice> list / String pageNavi
		//-> 메소드는 1개만 리턴이 가능 -> 되돌려주고싶은 데이터를 합친 객체를 만들어준다
		//->vo에 NoticePageData 클래스를 만들어서 거기에 ArrayList<Notice> list / String pageNavi 생성해줌
		NoticePageData npd = new NoticePageData(list, pageNavi, start);
		JDBCTemplate.close(conn);
		return npd;
	}

Dao

	public ArrayList<Notice> selectNoticeList(Connection conn, int start, int end) {
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		ArrayList<Notice> list = new ArrayList<Notice>();
		String query = "select * from (select rownum as rnum, n.* from(select notice_no, notice_title, notice_writer, read_count, reg_date from notice order by 1 desc)n) where rnum between ? and ?";
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, start);
			pstmt.setInt(2, end);
			rset = pstmt.executeQuery();
			while(rset.next()) {
				Notice n = new Notice();
				n.setNoticeNo(rset.getInt("notice_no"));
				n.setNoticeTitle(rset.getString("notice_title"));
				n.setNoticeWriter(rset.getString("notice_writer"));
				n.setReadCount(rset.getInt("read_count"));
				n.setRegDate(rset.getString("reg_date"));
				list.add(n);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCTemplate.close(pstmt);
			JDBCTemplate.close(rset);
		}
		return list;
	}

리스트를 보여줄 View

<%@page import="kr.or.iei.notice.model.vo.Notice"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%
    	ArrayList<Notice> list = (ArrayList<Notice>)request.getAttribute("list");
    	String pageNavi = (String)request.getAttribute("pageNavi");
    	int start = (int)request.getAttribute("start");
    %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
	.notice-tbl a:hover{
		text-decoration: underline;
	}
	.notice-tbl tr{
		border-bottom: 1px solid #ccc;
	}
	.notice-tbl tr>td:nth-child(2){
		text-align: left;
	}
	#pageNavi{
		margin: 30px;
	}
</style>
</head>
<body>
	<%@include file="/WEB-INF/views/common/header.jsp" %>
	<div class="page-content">
		<div class="page-title">공지사항</div>
		<%if(m!=null && m.getMemberLevel() == 1) {%>
		<a class="btn bc2 writeBtn" href="/noticeWriteFrm.do">글쓰기</a>
		<%} %>
		
		<table class="tbl tbl-hover notice-tbl">
			<tr class="tr-2">
				<th style="width:10%">번호</th>
				<th style="width:55%">제목</th>
				<th style="width:10%">작성자</th>
				<th style="width:10%">작성일</th>
				<th style="width:10%">조회수</th>
			</tr>
			<%for(int i=0; i<list.size(); i++) {%>
				<%Notice n = list.get(i); %>
			<tr class="tr-1">
				<td><%=i+start %></td>
				<td>
					<a href="/noticeView.do?noticeNo=<%=n.getNoticeNo() %>">
						<%=n.getNoticeTitle() %>
					</a>
				</td>
				<td><%=n.getNoticeWriter() %></td>
				<td><%=n.getRegDate() %></td>
				<td><%=n.getReadCount() %></td>
			</tr>
			<%} %>
		</table>
		<div id="pageNavi"><%=pageNavi %></div>
	</div>
	<%@include file="/WEB-INF/views/common/footer.jsp" %>
</body>
</html>

2. 공지사항 게시글 상세보기

타이틀을 클릭하면 해당 게시글의 상세내용을 확인

<td>
		<a href="/noticeView.do?noticeNo=<%=n.getNoticeNo() %>">
			<%=n.getNoticeTitle() %>
		</a>
</td>

게시글 조회를 위한 Controller(Servlet)

package kr.or.iei.notice.cotroller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.or.iei.notice.model.service.NoticeService;
import kr.or.iei.notice.model.vo.Notice;

/**
 * Servlet implementation class NoticeViewServlet
 */
@WebServlet(name = "NoticeView", urlPatterns = { "/noticeView.do" })
public class NoticeViewServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public NoticeViewServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1. 인코딩
		request.setCharacterEncoding("utf-8");
		//2. 값추출
		int noticeNo = Integer.parseInt(request.getParameter("noticeNo"));
		//3. 비즈니스로직
		NoticeService service = new NoticeService();
		Notice n = service.selectOneNotice(noticeNo);
		//4. 결과처리
		if(n == null) {
			RequestDispatcher view = request.getRequestDispatcher("/WEB-INF/views/common/msg.jsp");
			request.setAttribute("title", "조회 실패");
			request.setAttribute("msg", "게시글이 존재하지 않습니다.");
			request.setAttribute("icon", "info");
			request.setAttribute("loc", "/noticeList.do?reqPage=1");
			view.forward(request, response);
		}else {
			RequestDispatcher view = request.getRequestDispatcher("/WEB-INF/views/notice/noticeView.jsp");
			request.setAttribute("n", n);
			view.forward(request, response);
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

Service

	public Notice selectOneNotice(int noticeNo) {
		Connection conn = JDBCTemplate.getConnection();
		//상세보기를 하면 조회수가 1씩 카운트 해줘야함 - connection 닫기전에 해줘야한다.
		//업데이트가 먼저 발생해야 쿼리문을 읽어올 때 +1된 조회수를 얻을 수 있다.
		int result = dao.updateReadCount(conn, noticeNo);
		if(result > 0) {
			JDBCTemplate.commit(conn);
			Notice n = dao.selectOneNotice(conn, noticeNo);
			//return이 둘다 들어가고있으므로 close를 두 경우 다 해줘야한다.
			JDBCTemplate.close(conn);
			return n;
		}else {
			JDBCTemplate.rollback(conn);
			JDBCTemplate.close(conn);
			return null;
		}
	}

Dao 1 : 상세보기 시 조회수가 1씩 올라가야하므로 조회수를 update해줄 Dao

	public int updateReadCount(Connection conn, int noticeNo) {
		PreparedStatement pstmt = null;
		int result = 0;
		String query = "update notice set read_count = read_count+1 where notice_no = ?";
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, noticeNo);
			result = pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCTemplate.close(pstmt);
		}
		return result;
	}

 

Dao 2 : 정보를 조회해올 Dao

	public Notice selectOneNotice(Connection conn, int noticeNo) {
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		Notice n = null;
		String query = "select * from notice where notice_no = ?";
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, noticeNo);
			rset = pstmt.executeQuery();
			if(rset.next()) {
				n = new Notice();
				n.setFileName(rset.getString("filename"));
				n.setFilePath(rset.getString("filepath"));
				n.setNoticeContent(rset.getString("notice_content"));
				n.setNoticeNo(rset.getInt("notice_no"));
				n.setNoticeTitle(rset.getString("notice_title"));
				n.setNoticeWriter(rset.getString("notice_writer"));
				n.setReadCount(rset.getInt("read_count"));
				n.setRegDate(rset.getString("reg_date"));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JDBCTemplate.close(rset);
			JDBCTemplate.close(pstmt);
		}
		return n;
	}

상세내용을 보여주기위한 view

<%@page import="kr.or.iei.notice.model.vo.Notice"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%
    Notice n = (Notice)request.getAttribute("n");
    %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
	#noticeView th, #noticeView td{
		border: 1px solid #eee;
	}
	#noticeContent{
		text-align: left;
		min-height: 300px;
	}
</style>
</head>
<body>
	<%@include file="/WEB-INF/views/common/header.jsp" %>
	<div class="page-content">
		<div class="page-title">공지사항</div>
		<table class="tbl" id="noticeView">
			<tr class="tr-3">
				<th colspan="6"><%=n.getNoticeTitle() %>
			</tr>
			<tr class="tr-1">
				<th class="td-3">작성자</th>
				<td><%=n.getNoticeWriter() %>
				<th class="td-3">작성일</th>
				<td><%=n.getRegDate() %>
				<th class="td-3">조회수</th>
				<td><%=n.getReadCount() %>
			</tr>
			<tr class="tr-1">
				<th class="td-3">첨부파일</th>
				<td colspan="5">
				<%if(n.getFileName() != null) {%>
				<img src="/img/file.png" width="16px">
				<a href="/noticeFileDown.do?noticeNo=<%=n.getNoticeNo() %>"><%=n.getFileName() %></a>
				<%} %>
				</td>
			</tr>
			<tr>
				<td colspan="6">
					<div id="noticeContent">
						<%=n.getNoticeContentBr() %>
					</div>
				</td>
			</tr>
			<!-- if(m.getMemberId().equals(n.getNoticeWriter()))
			 조건을 이렇게만 주면 로그인을 하지 않았을 경우 에러발생 로그인조건을 걸어줘야한다. -->
			<%if( m!=null && m.getMemberId().equals(n.getNoticeWriter()) ) {%>
			<tr>
				<th colspan="6">
					<a class="btn bc44" href="/noticeUpdateFrm.do?noticeNo=<%=n.getNoticeNo() %>">수정</a>
					<button class="btn bc44" onclick="noticeDelete(<%=n.getNoticeNo()%>);">삭제</button>
				</th>
			</tr>
			<%} %>
		</table>
	</div>
	<%@include file="/WEB-INF/views/common/footer.jsp" %>
		
	<script>
		function noticeDelete(noticeNo){
			if(confirm("게시글을 삭제하시겠습니까?")){
				location.href="/deleteNotice.do?noticeNo="+noticeNo;
				//방법1.여기서는 noticeNo가 몇번인지 알 수 없으므로 매개변수로 넘겨줌
			}
		}
	</script>
</body>
</html>

3. 공지사항 삭제

- 관리자만 삭제가 가능하며 삭제버튼 클릭 시 confirm으로 확인을 먼저 받고 진행

삭제를 위한 Controller(Servlet)

package kr.or.iei.notice.cotroller;

import java.io.File;
import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.or.iei.notice.model.service.NoticeService;
import kr.or.iei.notice.model.vo.Notice;

/**
 * Servlet implementation class DeleteNoticeServlet
 */
@WebServlet(name = "DeleteNotice", urlPatterns = { "/deleteNotice.do" })
public class DeleteNoticeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DeleteNoticeServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1. 인코딩
		request.setCharacterEncoding("utf-8");
		//2. 값추출
		int noticeNo = Integer.parseInt(request.getParameter("noticeNo"));
		//3. 비즈니스로직
		NoticeService service = new NoticeService();
		//삭제라는 행동만 할거면 int로 받을 거지만
		//파일도 지워야하기때문에 filepath가 필요함 -> Notice로 받아옴
		Notice n = service.deleteNotice(noticeNo);
		//4. 결과처리
		RequestDispatcher view = request.getRequestDispatcher("/WEB-INF/views/common/msg.jsp");
		if(n != null) {
			//DB가 성공적으로 삭제되었을 때 첨부파일이 있는지 확인한 후 
			//첨부파일이 있을 경우 삭제
			if(n.getFilePath() != null) {
				String root = getServletContext().getRealPath("/");
				String deleteFile = root+"upload/notice/"+n.getFilePath();
				File delFile = new File(deleteFile);
				delFile.delete(); //파일삭제코드
			}
			request.setAttribute("title", "삭제성공");
			request.setAttribute("msg", "게시글이 삭제되었습니다.");
			request.setAttribute("icon", "success");
			request.setAttribute("loc", "/noticeList.do?reqPage=1");
		}else {
			request.setAttribute("title", "삭제실패");
			request.setAttribute("msg", "오류가 발생했습니다.");
			request.setAttribute("icon", "error");
			request.setAttribute("loc", "/noticeView.do?noticeNo"+noticeNo);
		}
		view.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

Service

	public Notice deleteNotice(int noticeNo) {
		Connection conn = JDBCTemplate.getConnection();
		Notice n = dao.selectOneNotice(conn, noticeNo);
		int result = dao.delectNotice(conn, noticeNo);
		if(result>0) {
			JDBCTemplate.commit(conn);
		}else {
			JDBCTemplate.rollback(conn);
			n = null;
		}
		JDBCTemplate.close(conn);
		return n;
	}

Dao

	public int delectNotice(Connection conn, int noticeNo) {
		PreparedStatement pstmt = null;
		int result = 0;
		String query = "delete from notice where notice_no = ?";
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, noticeNo);
			result = pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCTemplate.close(pstmt);
		}
		return result;
	}

 

4. 공지사항 수정

<a class="btn bc44" href="/noticeUpdateFrm.do?noticeNo=<%=n.getNoticeNo() %>">수정</a>

- 수정화면으로 이동하기위한 Servlet(기존정보도 조회해온다)

package kr.or.iei.notice.cotroller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.or.iei.notice.model.service.NoticeService;
import kr.or.iei.notice.model.vo.Notice;

/**
 * Servlet implementation class NoticeUpdateFrmServlet
 */
@WebServlet(name = "NoticeUpdateFrm", urlPatterns = { "/noticeUpdateFrm.do" })
public class NoticeUpdateFrmServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public NoticeUpdateFrmServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1. 인코딩
		request.setCharacterEncoding("utf-8");
		//2. 값추출
		int noticeNo = Integer.parseInt(request.getParameter("noticeNo"));
		//3. 비즈니스로직
		NoticeService service = new NoticeService();
		Notice n = service.getNotice(noticeNo);
		//4. 결과처리
		RequestDispatcher view = request.getRequestDispatcher("/WEB-INF/views/notice/noticeUpdateFrm.jsp");
		request.setAttribute("n", n);
		view.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

Serivce : 정보조회를 위한 코드

	public Notice getNotice(int noticeNo) {
		Connection conn = JDBCTemplate.getConnection();
		Notice n = dao.selectOneNotice(conn, noticeNo);
		JDBCTemplate.close(conn);
		return n;
	}

Dao : 정보조회를 위한 코드

	public Notice selectOneNotice(Connection conn, int noticeNo) {
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		Notice n = null;
		String query = "select * from notice where notice_no = ?";
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, noticeNo);
			rset = pstmt.executeQuery();
			if(rset.next()) {
				n = new Notice();
				n.setFileName(rset.getString("filename"));
				n.setFilePath(rset.getString("filepath"));
				n.setNoticeContent(rset.getString("notice_content"));
				n.setNoticeNo(rset.getInt("notice_no"));
				n.setNoticeTitle(rset.getString("notice_title"));
				n.setNoticeWriter(rset.getString("notice_writer"));
				n.setReadCount(rset.getInt("read_count"));
				n.setRegDate(rset.getString("reg_date"));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JDBCTemplate.close(rset);
			JDBCTemplate.close(pstmt);
		}
		return n;
	}

공지사항 수정 화면을 보여줄 View

<%@page import="kr.or.iei.notice.model.vo.Notice"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%
    Notice n = (Notice)request.getAttribute("n");
    %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%@include file="/WEB-INF/views/common/header.jsp" %>
	<div class="page-content">
		<div class="page-title">공지사항수정</div>
		<form action="/noticeUpdate.do" method="post" enctype="multipart/form-data">
			<table class="tbl" id="noticeUpdateFrm">
				<tr class="tr-1">
					<th class="td-3">제목</th>
					<td>
						<input type="text" name="noticeTitle" class="input-form" value="<%=n.getNoticeTitle() %>">
						<input type="hidden" name="status" value="stay">
						<input type="hidden" name="noticeNo" value="<%=n.getNoticeNo() %>">
					</td>
				</tr>
				<tr class="tr-1">
					<th class="td-3">첨부파일</th>
					<td>
						<!-- 
						<input type="file" name="upfile" value="<%=n.getFilePath() %>">
						input태그에 value를 작성하면 값이 보여야하지만 첨부파일은 보이지않음
						이유 : 일단 getFilePath()는 문자열형식 + 서버에있는 파일경로이므로 클라이언트가 알아봤자 의미가없다
						      보안의 문제도 있기 때문에 input type='file'에서는 value를 줄 수 없다 
						-->
						<!-- 
						-- 파일 경우의 수
						1. 기존 첨부파일이 있는 경우
						 -> 수정을 하지 않는 경우(oldFileName, oldFilePath로 update)
						 -> 첨부파일을 삭제만 한 경우(null로 upadate)
						 -> 기존파일을 삭제하고 새 파일을 첨부한경우(새 filename, 새 filepath로 update)
						
						2. 기존 첨부파일이 없는 경우
						 -> 수정을 하지 않는 경우(이미 null이지만 null로 update )
						 -> 새 첨부파일을 추가한 경우(새 filename, 새 filepath로 update )
						
						위 경우의 수를 만족할수있게 세팅을 해줘야한다.
						 -->
						<%if(n.getFilePath() != null) {%>
							<!-- 삭제하기를 누르면 한번에 둘다 안보이게 하기위해 같은 class를 주는것 -->
							<img src="/img/file.png" width="16px" class="delFile">
							<span class="delFile"><%=n.getFileName()%></span>
							<button type="button" class="btn bc1 delFile">삭제</button>
							<input type="file" name="upfile" style="display:none;">
							<input type="hidden" name="oldFilename" value="<%=n.getFileName() %>">
							<input type="hidden" name="oldFilepath" value="<%=n.getFilePath() %>">
						<%}else {%>
							<input type="file" name="upfile">
						<%} %>
					
					</td>
				</tr>
				<tr class="tr-1">
					<th class="td-3">내용</th>
					<td>
						<!-- textarea에서는 엔터가 먹으므로 엔터가 업는 NoticeContent를 사용 -->
						<textarea class="input-form" name="noticeContent"><%=n.getNoticeContent() %></textarea>
					</td>
				</tr>
				<tr class="tr-1">
					<th colspan="2">	
						<button type="submit" class="btn bc4 bs4">수정완료</button>
					</th>
				</tr>
			</table>
		</form>
	</div>
	<script>
		$("button.delFile").on("click", function(){
			$(".delFile").hide();
			$(this).next().show();
			//첨부파일이 있는 경우에 삭제를 누른 경우에만 stay -> delete
			$("[name=status]").val("delete");
		});
	</script>
	<%@include file="/WEB-INF/views/common/footer.jsp" %>
</body>
</html>

 

update를 진행해줄 Controller(Servlet)

package kr.or.iei.notice.cotroller;

import java.io.File;
import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

import kr.or.iei.notice.model.service.NoticeService;
import kr.or.iei.notice.model.vo.Notice;

/**
 * Servlet implementation class NoticeUpdateServlet
 */
@WebServlet(name = "NoticeUpdate", urlPatterns = { "/noticeUpdate.do" })
public class NoticeUpdateServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public NoticeUpdateServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1.인코딩
		request.setCharacterEncoding("utf-8");
		//2.값추출
		//2-1. 파일업로드 경로설정
		String root = getServletContext().getRealPath("/");
		String saveDirectory = root + "upload/notice";
		//2-2. 파일최대크기 지정
		int maxSize = 10*1024*1024;
		//2-3. request -> MultipartRequest 객체로 변환(파일업로드시점)
		MultipartRequest mRequest = new MultipartRequest(request, saveDirectory, maxSize, "utf-8", new DefaultFileRenamePolicy());
		
		int noticeNo = Integer.parseInt(mRequest.getParameter("noticeNo"));
		String noticeTitle = mRequest.getParameter("noticeTitle");
		String noticeContent = mRequest.getParameter("noticeContent");
		
		//기존파일이 지워졌으면 "delete", 그외에는 모두 "stay"(원래 파일이없거나, 지워지지않았을경우)
		String status = mRequest.getParameter("status"); 
		//새 첨부파일이 있으면 새 첨부파일 값, 없으면 null
		String filename = mRequest.getOriginalFileName("upfile");
		String filepath = mRequest.getFilesystemName("upfile");
		
		//기존 첨부파일이 있었으면 기존첨부파일 값, 없으면 null
		String oldFilename = mRequest.getParameter("oldFilename");
		String oldFilepath = mRequest.getParameter("oldFilepath");
		//oldFilename/oldFilepath가 있으면 기존파일이 있는경우
		if(oldFilename != null && status.equals("stay")) {
			//기존파일이 존재하고 삭제버튼을 눌렀을 경우
			filename = oldFilename;
			filepath = oldFilepath;
		}
		Notice n = new Notice();
		n.setNoticeNo(noticeNo);
		n.setNoticeTitle(noticeTitle);
		n.setNoticeContent(noticeContent);
		n.setFileName(filename);
		n.setFilePath(filepath);
	
		//3.비즈니스로직
		NoticeService service = new NoticeService();
		int result = service.updateNotice(n);
		//4.결과처리
		RequestDispatcher view = request.getRequestDispatcher("/WEB-INF/views/common/msg.jsp");
		if(result > 0) {
			request.setAttribute("title", "변경완료");
			request.setAttribute("msg", "공지사항이 수정되었습니다.");
			request.setAttribute("icon", "success");
			if(status.equals("delete")) {
				File delFile = new File(saveDirectory+"/"+oldFilepath);
				delFile.delete();
			}
		}else {
			request.setAttribute("title", "변경실패");
			request.setAttribute("msg", "관리자에게 문의하세요.");
			request.setAttribute("icon", "error");
		}
		request.setAttribute("loc", "/noticeView.do?noticeNo="+n.getNoticeNo());
		view.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

Service

	public int updateNotice(Notice n) {
		Connection conn = JDBCTemplate.getConnection();
		int result = dao.updateNotice(conn, n);
		if(result > 0) {
			JDBCTemplate.commit(conn);
		}else {
			JDBCTemplate.rollback(conn);
		}
		JDBCTemplate.close(conn);
		return result;
	}

Dao

	public int updateNotice(Connection conn, Notice n) {
		PreparedStatement pstmt = null;
		int result = 0;
		String query = "update notice set notice_title = ?, notice_content=?, filename = ?, filepath = ? where notice_no=?";
		
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, n.getNoticeTitle());
			pstmt.setString(2, n.getNoticeContent());
			pstmt.setString(3, n.getFileName());
			pstmt.setString(4, n.getFilePath());
			pstmt.setInt(5, n.getNoticeNo());
			result = pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCTemplate.close(pstmt);
		}
		return result;
	}

 

'국비수업 > Server' 카테고리의 다른 글

59일차 : AJAX, mvc2WebProject - 6  (0) 2023.02.21
58일차 - mvc2WebProject - 5  (0) 2023.02.21
56일차 : mvc2WebProject - 3  (0) 2023.02.16
55일차 : mvc2WebProject - 2  (0) 2023.02.16
54일차 : mvc2WebProject - 1  (0) 2023.02.16
Comments