-
Notifications
You must be signed in to change notification settings - Fork 0
공지사항
Gaeun Kim edited this page Feb 26, 2023
·
2 revisions
👆🏻 공지사항 메인 페이지
NoticeController
@PostMapping("/admin/write")
public String writeNotice(CommitMap commitMap, HttpServletRequest request) throws Exception {
noticeService.writeNotice(commitMap.getMap(), request);
return "redirect:/notice/list";
}
공지사항 작성 (C)
@GetMapping("/detail")
public ModelAndView getNoticeDetail(CommitMap commitMap, HttpServletRequest request) throws Exception {
/* 공지사항 상세, 공지사항 수정 페이지에서 getNoticeDetail 메소드 사용.
수정 페이지에서만 textarea태그 사이에 content를 넣어주는데 textarea는 br태그를 줄바꿈 태그로 인식 안함. 따라서 데이터를 꺼내올 때 br태그를 개행문자로 바꿔 줄 필요가 있다.
(상세에서는 필요X) 상세와 수정을 구분하기 위해 "detail"이라는 구분값을 넣어준다.*/
Map<String, Object> noticeDetail = noticeService.getNoticeDetail(commitMap.getMap(), request, "detail");
ModelAndView mv = new ModelAndView("/notice/detail");
if (noticeDetail.isEmpty()) {
mv.addObject("msg", "삭제된 게시글입니다.");
mv.addObject("path", "/notice/list");
mv.setViewName("/alert/alert");
} else {
mv.addObject("detail", noticeDetail.get("detail"));
mv.addObject("list", noticeDetail.get("list"));
}
return mv;
}
공지사항 상세 (R)
@PostMapping("/admin/update")
public ModelAndView updateNotice(CommitMap commitMap, HttpServletRequest request) throws Exception {
noticeService.updateNotice(commitMap.getMap(), request);
ModelAndView mv = new ModelAndView("redirect:/notice/detail");
mv.addObject("NOTICE_IDX", commitMap.get("NOTICE_IDX"));
return mv;
}
공지사항 수정 (U)
@PostMapping("/admin/delete")
public String deleteNotice(@RequestBody Map<String, Object> map) throws Exception {
noticeService.deleteNotice(map);
return "redirect:/notice/list";
}
공지사항 삭제 (D)
NoticeServiceImpl
@Override
public void writeNotice(Map<String, Object> map, HttpServletRequest request) throws Exception {
String originalContent = map.get("CONTENT").toString();
// 개행 문자 모두 <br>로 변경
String replaceContent = originalContent.replaceAll(System.lineSeparator(), "<br>");
map.put("CONTENT", replaceContent);
//공지사항 등록
noticeDAO.insertNotice(map);
List<Map<String, Object>> fileList = fileUtils.parseInsertFileInfo(map, request);
// 파일을 추가했다면
if (!fileList.isEmpty()) {
for (Map<String, Object> file : fileList) {
// 공지사항 파일 등록
noticeDAO.insertFile(file);
}
}
}
공지사항 작성 (C)
@Override
public Map<String, Object> getNoticeDetail(Map<String, Object> map, HttpServletRequest request, String state) throws Exception {
map = sessionHelper.make(map, request);
// 일반 회원일 때만 조회 수 증가
if (map.get("admin") == null) {
noticeDAO.updateHitCount(map);
}
// 게시글 (게시글 상세 내용과 파일 리스트를 포함한)
Map<String, Object> notice = new HashMap<>();
// 게시글 상세
Map<String, Object> detail = noticeDAO.selectNoticeDetail(map);
if (detail != null) {
if (state.equals("update")) {
// 수정시에만 <br>을 OS에 맞는 개행 문자로 변경
String originalContent = detail.get("CONTENT").toString();
String replaceContent = originalContent.replaceAll("<br>", System.lineSeparator());
detail.put("CONTENT", replaceContent);
}
List<Map<String, Object>> fileList = noticeDAO.selectFileList(map);
notice.put("detail", detail);
notice.put("list", fileList);
}
return notice;
}
공지사항 상세 (R)
@Override
public void updateNotice(Map<String, Object> map, HttpServletRequest request) throws Exception {
String originalContent = map.get("CONTENT").toString();
// 개행 문자 모두 <br>로 변경
String replaceContent = originalContent.replaceAll(System.lineSeparator(), "<br>");
map.put("CONTENT", replaceContent);
// 공지사항 수정
noticeDAO.updateNotice(map);
// 공지사항 파일 목록 전부 삭제 처리
noticeDAO.deleteFileList(map);
List<Map<String, Object>> fileList = fileUtils.parseUpdateFileInfo(map, request);
for (Map<String, Object> file : fileList) {
// IS_NEW의 값이 Y면 새로운 파일, N이면 기존 파일
if (file.get("IS_NEW").equals("Y")) {
noticeDAO.insertFile(file);
} else {
// 기존 파일일경우 DEL(삭제유무)값을 Y에서 N으로 변경
noticeDAO.updateFile(file);
}
}
}
공지사항 수정 (U)
@Override
public void deleteNotice(Map<String, Object> map) throws Exception {
// 글 삭제
noticeDAO.deleteNotice(map);
// 파일 삭제
noticeDAO.deleteFileList(map);
}
공지사항 삭제 (D)
Notice_SQL.xml
-- 공지사항을 등록함과 동시에 파일도 같이 등록해야 하기 때문에 NOTICE_IDX를 selectKey로 꺼내옴.
-- 파라미터로 들어온 hashmap에 NOTICE_IDX라는 이름으로 꺼내온 selectKey가 다시 담김.(keyProperty="NOTICE_IDX")
<insert id="insertNotice" parameterType="hashmap"
useGeneratedKeys="true" keyProperty="NOTICE_IDX">
<selectKey keyProperty="NOTICE_IDX" resultType="string"
order="BEFORE">
SELECT NOTICE_SEQ.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO NOTICE
(
NOTICE_IDX,
TITLE,
CONTENT
)
VALUES
(
#{NOTICE_IDX},
#{TITLE},
#{CONTENT}
)
</insert>
공지사항 작성 (C)
SELECT NOTICE_IDX,
TITLE,
CONTENT,
TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE,
HIT,
DEL
FROM NOTICE
WHERE NOTICE_IDX = #{NOTICE_IDX}
AND DEL = 'N'
공지사항 상세 (R)
SELECT FILE_IDX,
ORIGINAL_NAME,
ROUND(FILE_SIZE / 1024, 1) AS FILE_SIZE
FROM NOTICE_FILE
WHERE NOTICE_IDX = #{NOTICE_IDX}
AND DEL = 'N'
공지사항 상세 - 파일 목록 (R)
UPDATE NOTICE
SET TITLE = #{TITLE},
CONTENT = #{CONTENT}
WHERE NOTICE_IDX = #{NOTICE_IDX}
공지사항 수정 (U)
UPDATE NOTICE
SET DEL = 'Y'
WHERE NOTICE_IDX = #{NOTICE_IDX}
공지사항 삭제 (D)
공지사항 상세
- 업로드
- Request로 들어온 파일을 MultipartHttpServletRequest로 변환.
- multipart 파일들의 파라미터 이름을 Iterator에 담아줌.
- 서버의 절대경로를 구해 파일이 저장될 위치 설정.
- Iterator에 담긴 파일의 파라미터 이름으로 실제 파일 객체를 가져옴.
- 파일 객체가 있다면 DB에 저장될 파일의 이름을 UUID로 랜덤 생성.
- 3번에서 지정한 위치에 임시 이름으로 파일 업로드.
- selectKey로 뽑아온 공지사항 번호, 파일 원본 이름, 파일 임시 이름등을 DB에 저장.
- 수정
- 4번까지는 업로드와 동일하고, 파일을 수정하기 전 해당 게시글의 모든 파일은 삭제처리됨
- 실제 파일 객체가 있는지 확인
5-1. 객체가 있다면 새로 추가한 파일이므로 업로드와 동일하지만 "IS_NEW", "Y"라는 구분값을 추가.
5-2. 객체가 없다면 map에 'IDX_번호'로 이루어진 key가 있는지 확인 후, 있다면 기존 파일이므로 DEL(삭제유무)값 N으로 변경.
기존 파일이 남아 있을 경우 map에 "IDX_번호", "파일 인덱스 번호"(="key", "value")가 담겨있다.
FileUpload
public List<Map<String, Object>> parseInsertFileInfo(Map<String, Object> map, HttpServletRequest request) throws Exception {
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
Iterator<String> iterator = multipartHttpServletRequest.getFileNames();
// 서버의 절대경로를 구해 파일이 저장될 위치 설정.
String filePath = request.getSession().getServletContext().getRealPath("/") + "static/uploadFile/";
MultipartFile multipartFile;
String originalFileName;
String originalFileExtension;
String storedFileName;
List<Map<String, Object>> fileList = new ArrayList<>();
Map<String, Object> fileInfo;
//selectKey로 담긴 NOTICE_IDX
String noticeIdx = map.get("NOTICE_IDX").toString();
File file = new File(filePath);
// 해당 폴더가 없다면 생성
if (!file.exists()) {
file.mkdirs();
}
while (iterator.hasNext()) {
// 실제 파일 객체를 가져옴
multipartFile = multipartHttpServletRequest.getFile(iterator.next());
if (!multipartFile.isEmpty()) {
originalFileName = multipartFile.getOriginalFilename();
// 파일 이름에서 확장자만 분리
originalFileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
// UUID로 생성된 이름과 확장자를 합침
storedFileName = CommitUtils.getRandomString() + originalFileExtension;
// 위에서 설정한 경로와 생성된 이름으로 파일 업로드
file = new File(filePath + storedFileName);
multipartFile.transferTo(file);
fileInfo = new HashMap<>();
fileInfo.put("NOTICE_IDX", noticeIdx);
fileInfo.put("ORIGINAL_NAME", originalFileName);
fileInfo.put("STORED_NAME", storedFileName);
fileInfo.put("FILE_SIZE", multipartFile.getSize());
fileList.add(fileInfo);
}
}
return fileList;
}
파일 업로드
public List<Map<String, Object>> parseUpdateFileInfo(Map<String, Object> map, HttpServletRequest request) throws Exception {
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
Iterator<String> iterator = multipartHttpServletRequest.getFileNames();
String filePath = request.getSession().getServletContext().getRealPath("/") + "static/uploadFile/";
MultipartFile multipartFile;
String originalFileName;
String originalFileExtension;
String storedFileName;
List<Map<String, Object>> fileList = new ArrayList<>();
Map<String, Object> fileInfo;
String noticeIdx = map.get("NOTICE_IDX").toString();
String requestName;
String idx;
while (iterator.hasNext()) {
multipartFile = multipartHttpServletRequest.getFile(iterator.next());
if (!multipartFile.isEmpty()) {
originalFileName = multipartFile.getOriginalFilename();
originalFileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
storedFileName = CommitUtils.getRandomString() + originalFileExtension;
multipartFile.transferTo(new File(filePath + storedFileName));
fileInfo = new HashMap<>();
// 기존 파일과 구분하기 위해 "IS_NEW", "Y" 라는 값을 넣어줌. IS_NEW 값이 Y일 경우 insert
fileInfo.put("IS_NEW", "Y");
fileInfo.put("NOTICE_IDX", noticeIdx);
fileInfo.put("ORIGINAL_NAME", originalFileName);
fileInfo.put("STORED_NAME", storedFileName);
fileInfo.put("FILE_SIZE", multipartFile.getSize());
fileList.add(fileInfo);
} else {
// <input type="file" name="file_${var.index }"/>에서 name값인 file_${var.index }를 가져옴
requestName = multipartFile.getName();
// file_${var.index }에서 _뒤에 숫자만 추출 후 "IDX_"랑 합침.
idx = "IDX_" + requestName.substring(requestName.indexOf("_") + 1);
/* 기존 파일인 경우 <input type="hidden" name="IDX_${var.index }" value="${row.FILE_IDX }">에서
name과 value가 map에 담겨있음.(input type hidden으로 날라옴)
(기존 파일을 삭제했을 경우에는 담겨있지않음. 신규로 생성된 파일도 담겨있지않음.) */
if (map.containsKey(idx) && !"".equals(map.get(idx))) {
fileInfo = new HashMap<>();
// IS_NEW 값이 N일 경우 update, DEL 값을 Y에서 N으로
fileInfo.put("IS_NEW", "N");
// 기존 파일 인덱스 번호
fileInfo.put("FILE_IDX", map.get(idx));
fileList.add(fileInfo);
}
}
}
return fileList;
}
파일 수정
FileDownload
@Override
public void downloadFile(Map<String, Object> commitMap, HttpServletResponse response, HttpServletRequest request) throws Exception {
// 파일 정보를 꺼내옴
Map<String, Object> fileInfo = noticeDAO.selectFileInfo(commitMap);
// 임시 저장 이름
String storedFileName = fileInfo.get("STORED_NAME").toString();
// 파일 실제 이름
String originalFileName = fileInfo.get("ORIGINAL_NAME").toString();
String filePath = request.getSession().getServletContext().getRealPath("/") + "static/uploadFile/";
// 파일이 업로드 된 경로에서 임시 이름으로 저장된 파일을 읽어 byte배열에 담음
byte[] fileByte = org.apache.commons.io.FileUtils.readFileToByteArray(new File(filePath + storedFileName));
response.setContentType("application/octet-stream");
response.setContentLength(fileByte.length);
response.setHeader("Content-Disposition", "attachment; fileName=\"" + URLEncoder.encode(originalFileName, StandardCharsets.UTF_8) + "\";");
response.setHeader("Content-Transfer-Encoding", "binary");
// byte[]타입으로 변환된 file을 response를 통해 client에게 전송
response.getOutputStream().write(fileByte);
response.getOutputStream().flush();
response.getOutputStream().close();
}
파일 다운로드