1. MVNrepository 에서 추가 필요 파일 다운로드 (jar파일)
- commons-fileiplode-1.4
- commons-io-2.11.0
- thumbnailator-0.4.17
- 지금까지 다운받은 항목 -
다운받았으면 lip파일에 넣어주기
2. webapp 폴더에 _fileuplode폴더 생성
: _는 제일 상단에 위치하게 하기위해서 설정 (이름 오타안나게 주의!)
3. commons 패키지를 이용하여 파일 업로드할 예정!
- thumbnail기능 : 큰 사진들을 빠르게 업로드할 수 있도록 (속도를 높이기 위해) 작게 줄여서 가져오는 기능
- ppt파일 확인 - 30페이지부터
== 파일 업로드 처리 순서 ==
1. 폼 데이터가 multipart/form-data 형식으로 전송되었는지 확인 합니다.
= 그래야 parameter로 가져오기가 가능
2. 업로드된 파일과 폼 데이터를 담는 DiskFileUpload객체를 생성합니다.
= 이미지파일+여러 정보가 담길 객체 생성
3. DiskFileUpload 객체에서 아이템들을 추출합니다.
= 아이템 : 이미지파일, 정보 등
4. 추출된 아이템을 하나씩 꺼내서 폼데이터인지 파일인지 분석하여 각각 처리를 작성합니다.
= 데이터들은 DB에/ 이미지는 따로 저장 + DB에 이미지의 주소(경로)를 저장!
== register.jsp ==
4. board폴더의 register.jsp에 ( enctype / imageFile받는 input ) 추가
- 폼 데이터를 multipart/form-data 형식으로 전송 = 그래야 parameter로 가져오기가 가능
- 추가부분
<form action="/brd/insert" method="post" enctype="multipart/form-data">
imageFile : <input type="file" id="file" name="image_file"
accept="image/png, image/jpg, image/jpeg, image/bmp, image/gif"> <br><br>
- 최종
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Board Register Page</title>
</head>
<body>
<h1>register page</h1>
<form action="/brd/insert" method="post" enctype="multipart/form-data">
title : <input type="text" name="title"> <br>
writer : <input type="text" name="writer" value="${ses.id }" readonly="readonly"> <br>
content : <textarea rows="3" cols="30" name="content"></textarea> <br>
imageFile : <input type="file" id="file" name="image_file"
accept="image/png, image/jpg, image/jpeg, image/bmp, image/gif"> <br>
<!-- accept = placeholder처럼 사용하는거라 선택! -->
<button type="submit">등록</button>
</form>
</body>
</html>
5. board table에 파일경로가 들어갈 칼럼 추가
+ resources폴더 schema.sql에 칼럼추가부분 저장
alter table board add image_file varchar(100); // text도 가능
// text로 변경 시
alter table board modify image_file text;
== boardVO ==
6. boardVO 멤버변수에 image_file 추가
package domain;
public class BoardVO {
/* create table board(
bno int not null auto_increment,
title varchar(100) not null,
writer varchar(100) not null,
content text,
reg_date datetime default now(),
primary key(bno));
*
* */
private int bno;
private String title;
private String writer;
private String content;
private String reg_date;
private int count;
private String image_file;
public BoardVO() {}
//register(title, writer, content)
public BoardVO(String title, String writer, String content) {
this.title = title;
this.writer = writer;
this.content = content;
}
//list(bno, title, writer, reg_date, count)
public BoardVO(int bno, String title, String writer, String reg_date, int count) {
this.bno = bno;
this.title = title;
this.writer = writer;
this.reg_date = reg_date;
this.count = count;
}
//datail(전체)
public BoardVO(int bno, String title, String writer, String content,
String reg_date, int count, String image_file) {
this.bno = bno;
this.title = title;
this.writer = writer;
this.content = content;
this.reg_date = reg_date;
this.count = count;
this.image_file = image_file;
}
//update(bno, title, content)
public BoardVO(int bno, String title, String content) {
this.bno = bno;
this.title = title;
this.content = content;
}
//getter,setter
public int getBno() {
return bno;
}
public void setBno(int bno) {
this.bno = bno;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getReg_date() {
return reg_date;
}
public void setReg_date(String reg_date) {
this.reg_date = reg_date;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getImage_file() {
return image_file;
}
public void setImage_file(String image_file) {
this.image_file = image_file;
}
@Override
public String toString() {
return "BoardVO [bno=" + bno + ", title=" + title + ", writer=" + writer + ", content=" + content
+ ", reg_date=" + reg_date + ", count=" + count + ", image_file=" + image_file + "]";
}
}
== BoardController ==
7. boardController 에 추가 + case "insert" 변경
- 상단 멤버변수에 추가 -
//파일 경로를 저장할 변수
private String savePath;
private final String UTF8 = "UTF-8"; //인코딩 설정시
- case "insert" 변경 -
case "insert":
try {
//파일을 업로드할 물리적인 경로를 설정
savePath = getServletContext().getRealPath("/_fileUpload");
log.info(">>>파일 저장 경로: " + savePath);
//실제경로를 가져와! "webapp안의_fileUplode"
File fileDir = new File(savePath); //File은 java.io에서 import
//파일의 저장위치를 담고 있는 객체생성
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
//아이템을 담는,,?
fileItemFactory.setRepository(fileDir);
//파일의 저장위치를 담고 있는 객체를 저장하기
fileItemFactory.setSizeThreshold(2*1024*1024);
//파일 저장을 위한 임시 메모리의 용량을 설정하기 : byte단위 => 2MB = 2*1024*1024
BoardVO bvo = new BoardVO();
ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
//multipart/form-data형식으로 넘어온 request객체를 다루기 쉽게 변환해주는 역할
List<FileItem> itemList = fileUpload.parseRequest(request);
//request객체를 FileItem의 리스트로 담아
for(FileItem item : itemList) {
//title = __, writer=__..이런식으로 key=velue 형태롤 들어가 있음
switch(item.getFieldName()) { //key값을 가져오는 역할
case "title":
bvo.setTitle(item.getString(UTF8));
//가져올때는 인코딩 형식을 담아서 변환해 가져와야 안깨짐!
//UTF8( 위에 "UTF-8"을 저장해놓은 변수) 또는 "UTF-8"로 작성가능
break;
case "writer":
bvo.setWriter(item.getString(UTF8));
break;
case "content":
bvo.setContent(item.getString(UTF8));
break;
case "image_file":
//먼저 이미지가 있는지 없는지부터 체크
if(item.getSize() > 0) { //데이터의 크기로 유무확인 (size) //이미지 파일이 있는 경우
String fileName = item.getName().substring(item.getName().lastIndexOf("/")+1);
log.info(">>>fileName 시간넣기 전 : " + fileName); //cat.jpg
//.getName() : 경로를 포함한 파일의 이름 (___.___/cat.jpg) -> 마지막 cat.jpg만 가져오기
fileName = System.currentTimeMillis()+"_"+fileName;
log.info(">>>fileName 시간넣은 후 : " + fileName);
//파일 이름 앞에 _저장시간넣어주기
File uploadFilePath = new File(fileDir+File.separator+fileName);
log.info(">>>실제 업로드하는 파일의 경로: "+ uploadFilePath);
try {
item.write(uploadFilePath); //자바객체를 디스크에 저장
bvo.setImage_file(fileName);
//썸네일 작업 : 리스트페이지에서 트래픽 과다사용을 막기위해
Thumbnails.of(uploadFilePath).size(75, 75)
.toFile(new File(fileDir+File.separator+"th_"+fileName));
} catch (Exception e) {
log.info("파일 저장 오류 발생! file writer on disk fail");
e.printStackTrace();
}
}
break;
}
}
isOk = bsv.insert(bvo);
log.info(">>> insert " + (isOk > 0 ? "성공" : "실패"));
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage = "page";
break;
- 변경된 boardController 전체부분 -
package controller;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import domain.BoardVO;
import domain.PagingVO;
import handle.PagingHandler;
import net.coobird.thumbnailator.Thumbnails;
import service.BoardService;
import service.BoardServiceImpl;
@WebServlet("/brd/*")
public class BoradController extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(BoradController.class);
private RequestDispatcher rdp; //목적지주소로 원하는값들 이동
private String destPage; //목적지 주소를 저장해주는 변수
private int isOk; //DB의 insert, update, delete의 결과를 받는 변수
private BoardService bsv; //인터페이스 생성
//파일 경로를 저장할 변수
private String savePath;
private final String UTF8 = "UTF-8"; //인코딩 설정시
public BoradController() {
bsv = new BoardServiceImpl(); //인터페이스의 구현체 생성(class)
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8"); //html형태로 가져와서 뿌려라!
String uri = request.getRequestURI(); //전체 요청경로
log.info(">>uri: " +uri);
String path = uri.substring(uri.lastIndexOf("/")+1);
log.info(">>path: " +path);
switch(path) {
case "register":
destPage = "/board/register.jsp";
break;
case "insert":
try {
//파일을 업로드할 물리적인 경로를 설정
savePath = getServletContext().getRealPath("/_fileUpload");
log.info(">>>파일 저장 경로: " + savePath);
//실제경로를 가져와! "webapp안의_fileUplode"
File fileDir = new File(savePath); //File은 java.io에서 import
//파일의 저장위치를 담고 있는 객체생성
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
//아이템을 담는,,?
fileItemFactory.setRepository(fileDir);
//파일의 저장위치를 담고 있는 객체를 저장하기
fileItemFactory.setSizeThreshold(2*1024*1024);
//파일 저장을 위한 임시 메모리의 용량을 설정하기 : byte단위 => 2MB = 2*1024*1024
BoardVO bvo = new BoardVO();
ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
//multipart/form-data형식으로 넘어온 request객체를 다루기 쉽게 변환해주는 역할
List<FileItem> itemList = fileUpload.parseRequest(request);
//request객체를 FileItem의 리스트로 담아
for(FileItem item : itemList) {
//title = __, writer=__..이런식으로 key=velue 형태롤 들어가 있음
switch(item.getFieldName()) { //key값을 가져오는 역할
case "title":
bvo.setTitle(item.getString(UTF8));
//가져올때는 인코딩 형식을 담아서 변환해 가져와야 안깨짐!
//UTF8( 위에 "UTF-8"을 저장해놓은 변수) 또는 "UTF-8"로 작성가능
break;
case "writer":
bvo.setWriter(item.getString(UTF8));
break;
case "content":
bvo.setContent(item.getString(UTF8));
break;
case "image_file":
//먼저 이미지가 있는지 없는지부터 체크
if(item.getSize() > 0) { //데이터의 크기로 유무확인 (size) //이미지 파일이 있는 경우
String fileName = item.getName().substring(item.getName().lastIndexOf("/")+1);
log.info(">>>fileName 시간넣기 전 : " + fileName); //cat.jpg
//.getName() : 경로를 포함한 파일의 이름 (___.___/cat.jpg) -> 마지막 cat.jpg만 가져오기
fileName = System.currentTimeMillis()+"_"+fileName;
log.info(">>>fileName 시간넣은 후 : " + fileName);
//파일 이름 앞에 _저장시간넣어주기
File uploadFilePath = new File(fileDir+File.separator+fileName);
log.info(">>>실제 업로드하는 파일의 경로: "+ uploadFilePath);
try {
item.write(uploadFilePath); //자바객체를 디스크에 저장
bvo.setImage_file(fileName);
//썸네일 작업 : 리스트페이지에서 트래픽 과다사용을 막기위해
Thumbnails.of(uploadFilePath).size(75, 75)
.toFile(new File(fileDir+File.separator+"th_"+fileName));
} catch (Exception e) {
log.info("파일 저장 오류 발생! file writer on disk fail");
e.printStackTrace();
}
}
break;
}
}
isOk = bsv.insert(bvo);
log.info(">>> insert " + (isOk > 0 ? "성공" : "실패"));
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage = "page";
break;
// try {
// String title = request.getParameter("title");
// String writer = request.getParameter("writer");
// String content = request.getParameter("content");
//
// BoardVO bvo = new BoardVO(title, writer, content);
//
// isOk = bsv.insert(bvo);
// log.info(">>> insert " + (isOk > 0 ? "성공" : "실패"));
//
//
// } catch (Exception e) {
// log.info("controller오류");
// e.printStackTrace();
// }
// destPage = "/";
// break;
case "list":
try {
List<BoardVO> list = new ArrayList<>();
list = bsv.list();
request.setAttribute("list", list);
log.info(">>> list출력");
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage = "page";
break;
case "page":
try {
int pageNo = 1;
int qty = 10;
//검색
String type ="";
String keyword="";
if(request.getParameter("type") != null) {
type = request.getParameter("type");
keyword = request.getParameter("keyword");
log.info(">>> type : " + type + "/ >>> ketword: " + keyword);
}
if(request.getParameter("pageNo") != null) {
pageNo = Integer.parseInt(request.getParameter("pageNo"));
qty = Integer.parseInt(request.getParameter("qty"));
}
PagingVO pgvo = new PagingVO(pageNo, qty);
pgvo.setType(type);
pgvo.setKeyword(keyword);
log.info(">>> pgvo set설정확인: "+pgvo.toString());
//전체 페이지의 개수
int totCount = bsv.getTotal(pgvo);
log.info("전체페이지의 수: "+totCount);
//limit을 이용해 맞는 select List호출!
//startPage, qty
List<BoardVO> list = bsv.getPageList(pgvo);
log.info(">>> list.size: "+ list.size());
PagingHandler ph = new PagingHandler(pgvo, totCount);
request.setAttribute("pgh", ph);
request.setAttribute("list", list);
log.info("pageList 성공");
} catch (Exception e) {
e.printStackTrace();
}
destPage = "/board/list.jsp";
break;
case "detail":
try {
int bno = Integer.parseInt(request.getParameter("bno"));
BoardVO bvo = new BoardVO();
request.setAttribute("bvo", bsv.detail(bno));
log.info(">>> 게시판 상세가져오기 성공");
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage = "/board/detail.jsp";
break;
case "modify":
try {
int bno = Integer.parseInt(request.getParameter("bno"));
BoardVO bvo = new BoardVO();
request.setAttribute("bvo", bsv.modify(bno));
log.info(">>> 게시판 수정에 가져오기 성공");
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage = "/board/modify.jsp";
break;
case "edit":
try {
int bno = Integer.parseInt(request.getParameter("bno"));
String title = request.getParameter("title");
String content = request.getParameter("content");
log.info(title);
BoardVO bvo = new BoardVO(bno, title, content);
isOk = bsv.edit(bvo);
log.info(">>> edit " + (isOk > 0 ? "성공" : "실패"));
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage="/brd/page";
break;
case "remove":
int bno = Integer.parseInt(request.getParameter("bno"));
isOk = bsv.remove(bno);
log.info(">>> remove " + (isOk > 0 ? "성공" : "실패"));
destPage="/brd/page";
break;
}
rdp = request.getRequestDispatcher(destPage);
rdp.forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
service(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
service(request, response);
}
}
== boardMapper ==
8. 연결되어있는 boardMapper의 insert구문에 image_file 추가
<insert id="reg" parameterType="bvo"> <!-- mvo = domain.mvo / mvo = mvo객체가 들어올꺼야! -->
insert into board(title, writer, content, image_file)
values(#{title}, #{writer}, #{content}, #{image_file})
</insert>
- 여기까지 하면 나오는 출력화면 -
9. list에 이미지가 작게(썸네일) 출력되도록 만들기
- 썸네일을 넣을 위치 -
- borad의 list.jsp에 추가 -
<tbody>
<c:forEach items="${list }" var="list">
<tr>
<td>${list.bno }</td>
<td>
<c:if test="${list.image_file ne null && list.image_file ne ''}">
<img alt="사진안떠욥" src="/_fileUpload/th_${list.image_file}">
</c:if>
<a href="detail?bno=${list.bno}">${list.title }</a>
</td>
<td>${list.writer }</td>
<td>${list.reg_date }</td>
<td>${list.count }</td>
</tr>
</c:forEach>
</tbody>
- boradMapper에 image_file추가 -
<select id="selectList" parameterType="pgvo" resultType="bvo">
select * from (
select bno from board where bno>0
<include refid="search"></include>
order by bno desc
limit #{pageStart}, #{qty}
) a left join board b
on a.bno = b.bno
</select>
//--------------------------------------------------------------------------
<select id="selectList" parameterType="pgvo" resultType="bvo">
select a.bno, title, writer, reg_date, count, image_file from (
select bno from board where bno>0
<include refid="search"></include>
order by bno desc
limit #{pageStart}, #{qty}
) a left join board b
on a.bno = b.bno
</select>
== 최종 출력화면 ==
== 이미지파일 상세페이지에 뜨도록 설정 ==
1. detail상세 페이지에 그림파일 원본 출력하기
<tr>
<th>첨부파일</th>
<td>
<c:if test="${bvo.image_file ne null && bvo.image_file ne ''}">
<img alt="사진안떠욥" src="/_fileUpload/${bvo.image_file}">
</c:if>
</td>
</tr>
== 이미지파일 수정하기 ==
1. board폴더의 modify 수정페이지에 파일수정 추가
- 추가부분
<form action="/brd/modify" method="post" enctype="multipart/form-data">
<tr>
<th>첨부파일</th>
<td>
<img alt="이미지 없송" src="/_fileUpload/th_${bvo.image_file}">
<input type="hidden" name="image_file" value="${bvo.image_file}">
<input type="file" name="new_file">
</td>
</tr>
- 최종
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>modify 게시판 수정</title>
</head>
<body>
<h3>modify 게시판 수정 페이지</h3>
<form action="/brd/edit" method="post" enctype="multipart/form-data">
<table class="table table-hover">
<tr>
<th>번호</th>
<td><input type="text" name="bno" value="${bvo.bno }" readonly="readonly"></td>
</tr>
<tr>
<th>제목</th>
<td><input type="text" name="title" value="${bvo.title }"></td>
</tr>
<tr>
<th>사용자</th>
<td><input type="text" name="writer" value="${bvo.writer }" readonly="readonly"></td>
</tr>
<tr>
<th>내용</th>
<td><textarea name="content">${bvo.content }</textarea></td>
</tr>
<tr>
<th>작성일자</th>
<td><input type="text" name="reg_date" value="${bvo.reg_date }" readonly="readonly"></td>
</tr>
<tr>
<th>첨부파일</th>
<td>
<img alt="이미지 없슈" src="/_fileUpload/th_${bvo.image_file}"> <!-- 기존 이미지 -->
<input type="hidden" name="image_file" value="${bvo.image_file}"><!-- 기존이미지 주소 -->
<input type="file" name="new_file"> <!-- 새 이미지 -->
</td>
</tr>
</table>
<button type="submit" onclick="handClick()">수정</button>
</form>
<script type="text/javascript"> //js를 사용하겠습니다
function handClick() {
alert("수정하였습니다.");
}
</script>
</body>
</html>
2. boardController에 case "edit" 새로 작성
case "edit":
try {
savePath = getServletContext().getRealPath("/_fileUpload");
File fileDir = new File(savePath);
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
fileItemFactory.setRepository(fileDir);
fileItemFactory.setSizeThreshold(2*1024*1024);
BoardVO bvo = new BoardVO();
ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
log.info(">>>update 준비");
List<FileItem> itemList = fileUpload.parseRequest(request);
String old_file = null;
for(FileItem item : itemList) {
switch(item.getFieldName()) {
case "bno":
bvo.setBno(Integer.parseInt( item.getString(UTF8)));
break;
case "title":
bvo.setTitle(item.getString(UTF8));
break;
case "content":
bvo.setContent(item.getString(UTF8));
break;
case "image_file":
//기존 파일의 이름을 가져와서 담기
old_file = item.getString(UTF8);
break;
case "new_file":
if(item.getSize() > 0) {
//수정할 이미지 파일(등록할)이 있는 경우
if(old_file != null) {
//old_file이 있는 경우
//파일핸들러를 호출해서 기존 파일을 삭제
FileHandler fileHandler = new FileHandler();
isOk = fileHandler.deleteFile(old_file, savePath);
}
//이름 설정
String fileName = item.getName().substring(
item.getName().lastIndexOf("/")+1);//이름
//lastIndexOf(File.separatoe)+1도 동일
log.info(">>>new_fileName : "+ fileName);
//실제저장이름
fileName = System.currentTimeMillis()+"_"+fileName;
File uploadFilePath = new File(fileDir + File.separator + fileName);
try {
item.write(uploadFilePath);
bvo.setImage_file(fileName);
log.info(">>> bvo.image_file : " + bvo.getImage_file());
//썸네일 작업
Thumbnails.of(uploadFilePath).size(75, 75)
.toFile(new File(fileDir+File.separator+"th_"+fileName));
} catch (Exception e) {
log.info(">>> file update on disk fall");
e.printStackTrace();
}
}else {//새로운파일을 넣지 않은 경우
bvo.setImage_file(old_file);
//기존의 파일을 다시 bvo객체에 저장하기
}
break;
}
}
isOk = bsv.edit(bvo);
log.info(">>> edit " + (isOk > 0 ? "성공" : "실패"));
} catch (Exception e) {
log.info("controller오류");
e.printStackTrace();
}
destPage="/brd/page";
break;
3. boardMapper의 update문 추가하면 끝!
<update id="update" parameterType="bvo">
update board set title=#{title}, content=#{content}, image_file=#{image_file} where bno=#{bno}
</update>
== 수정 실행 화면 ==
== 이미지파일 삭제 (컴퓨터에 저장된 이미지파일) ==
-- 1번방법 : 파라미터로 값을 보내서 삭제하기 --
1. board파일의 detail.jsp에서 삭제버튼 클릭시 ) 파라미터에 image_file이름 추가
- 상세게시판 detail.jsp 추가코드
<a href="/brd/remove?bno=${bvo.bno }&fileName=${bvo.image_file}"><button type="button">삭제</button></a>
- 상세게시판 detail.jsp 전체코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<title>detail 상세정보</title>
</head>
<body>
<h3>-- detail 게시판 상세 페이지 --</h3>
<table class="table table-hover">
<tr>
<th>번호</th>
<td>${bvo.bno }</td>
</tr>
<tr>
<th>제목</th>
<td>${bvo.title }</td>
</tr>
<tr>
<th>사용자</th>
<td>${bvo.writer }</td>
</tr>
<tr>
<th>내용</th>
<td>${bvo.content }</td>
</tr>
<tr>
<th>작성일자</th>
<td>${bvo.reg_date }</td>
</tr>
<tr>
<th>조회수</th>
<td>${bvo.count }</td>
</tr>
<tr>
<th>첨부파일</th>
<td>
<c:if test="${bvo.image_file ne null && bvo.image_file ne ''}">
<img alt="사진안떠욥" src="/_fileUpload/${bvo.image_file}">
</c:if>
</td>
</tr>
</table>
<a href="/brd/modify?bno=${bvo.bno }"><button type="button">수정</button></a>
<a href="/brd/remove?bno=${bvo.bno }&fileName=${bvo.image_file}"><button type="button">삭제</button></a>
<a href="/brd/page"><button type="button">리스트로 돌아가기</button></a>
<br><br><hr><br><br>
<h3>-- Comment line --</h3><br>
<!-- 댓글 작성 라인 -->
<h4>댓글 작성</h4>
<!-- js로 가져와 사용할 예정이라 id, button type="button" 사용 -->
<input type="text" id="cmtWriter" value="${ses.id }" placeholder="writer" readonly="readonly"> <br>
<input type="text" id="cmtText" placeholder="Add Comment">
<button type="button" id="cmtAddBtn">댓글 등록</button><br>
</div>
<br><br><hr><br><br>
<!-- 댓글 표시 라인 -->
<h4>작성된 댓글</h4>
<div class="accordion accordion-flush" id="accordionFlushExample">
<div class="accordion-item">
<h2 class="accordion-header" id="flush-headingOne">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseOne" aria-expanded="false" aria-controls="flush-collapseOne">
cno ,writer
</button>
</h2>
<div id="flush-collapseOne" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">
content, reg_date
</div>
</div>
</div>
</div>
<script type="text/javascript"> //번호 보내기
const bnoVal = `<c:out value = "${bvo.bno}" />`;
</script>
<script src="/resources/board_detail.js"></script>
<!-- 상단에 번호 보내기 사용가능 -->
<script type="text/javascript">
printCommentList(bnoVal);
</script>
</html>
2. handle패키지에 FileHandler(class) 생성
package handle;
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileHandler {
private static Logger log = LoggerFactory.getLogger(FileHandler.class);
//파일이름과 정보를 받아서 파일을 삭제하는 메서드
// 리턴타입:int = 삭제되었는지 확인하는 isOk
public int deleteFile(String imageFileName, String savePath) {
boolean isDel = false;
log.info(">>>deleteFile method 접근");
log.info(">>>imageFileName? : " + imageFileName);
//파일삭제시 리턴값이 boolean으로 와여
File fileDir = new File(savePath); //경로를 담은 파일
File removeFile = new File(fileDir + File.separator + imageFileName);
File removeThumbFile = new File(fileDir + File.separator + "th_" + imageFileName);
//파일이 있는지(존재하는지) 확인 -> 있으면 삭제
if(removeFile.exists() || removeThumbFile.exists()) { //있다면
isDel = removeFile.delete(); //리턴형태 boolean으로 나옴
log.info(">>> removeFile 값이 삭제되었는가? " + (isDel ? "OK" : "Fail"));
if(isDel) { //removFile이 없어졌다면 removeThumbFile도 삭제
isDel = removeThumbFile.delete();
log.info(">>> removeThumbFile 값이 삭제되었는가? " + (isDel ? "OK" : "Fail"));
}
}
log.info(">>>FileHandler remove OK! ");
return isDel? 1 : 0; //true면 1 아니면 0을 리턴
}
}
3. BoardController에서 case "delete"에 파일삭제 코드 작성
case "remove":
//DB삭제
int bno = Integer.parseInt(request.getParameter("bno"));
isOk = bsv.remove(bno);
log.info(">>> remove " + (isOk > 0 ? "성공" : "실패"));
//저장한 파일 사진 삭제
savePath = getServletContext().getRealPath("/_fileUpload");
File fileDir = new File(savePath);
String fileName = request.getParameter("fileName");
FileHandler han = new FileHandler();
int isOk2 = han.deleteFile(fileName, savePath);
log.info(">>> removeFile ?" + (isOk2 > 0 ? "성공" : "실패"));
//이동
destPage="/brd/page";
break;
-- 2번방법 : DB에서 이름을 가져와서 삭제하기 --
1. 1번 방법의 2번 - handle패키지에 FileHandler(class) 생성하기
2. BoardController에서 case "delete"에 파일삭제 코드 작성
DB에서 받아오는 경우!
1) bsv.remove(bno);에서 받아오는 리턴값을 bvo 객체로 받아오기
2) 받아온 bvo객체에서 image_file의 이름만 추출해서 String fileName에 저장
3) FileHandler han = new FileHandler();
int isOk2 = han.deleteFile(fileName, savePath);
== 삭제 실행 화면 ==
'JSP > JSP' 카테고리의 다른 글
[jsp] 결과갯수 배지 생성 / 내 게시물 출력 (사용자가 작성한 게시물) (0) | 2023.05.31 |
---|---|
[jsp] 검색기능 (0) | 2023.05.31 |
[jsp] list 페이징처리 (2) | 2023.05.31 |
[jsp] 댓글 6. 댓글 삭제 ( delete ) (0) | 2023.05.31 |
[jsp] 댓글 5. 댓글 수정 ( modify ) (0) | 2023.05.31 |