✿∘˚˳°∘°
57일차 : mvc2WebProject - 4 본문
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