diff --git a/pom.xml b/pom.xml index 322358cf..cd5ce8c8 100644 --- a/pom.xml +++ b/pom.xml @@ -207,7 +207,24 @@ tiles-jsp 3.0.8 - + + + + com.fasterxml.jackson.core + jackson-core + 2.11.4 + + + com.fasterxml.jackson.core + jackson-annotations + 2.11.4 + + + com.fasterxml.jackson.core + jackson-databind + 2.11.4 + + diff --git a/src/main/java/nlib/bbs/web/BoardController.java b/src/main/java/nlib/bbs/web/BoardController.java index 66d5e4db..9f0e97a3 100644 --- a/src/main/java/nlib/bbs/web/BoardController.java +++ b/src/main/java/nlib/bbs/web/BoardController.java @@ -1,15 +1,22 @@ package nlib.bbs.web; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import egovframework.com.cmm.service.FileVO; import nlib.bbs.service.BoardService; @Controller diff --git a/src/main/java/nlib/cmm/exception/ErrorMessage.java b/src/main/java/nlib/cmm/exception/ErrorMessage.java new file mode 100644 index 00000000..7488cce9 --- /dev/null +++ b/src/main/java/nlib/cmm/exception/ErrorMessage.java @@ -0,0 +1,17 @@ +package nlib.cmm.exception; + +public class ErrorMessage { + + String code = null; + String message = null; + + public ErrorMessage() { + super(); + } + + public ErrorMessage(String code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/src/main/java/nlib/cmm/fileupload/FileUploadController.java b/src/main/java/nlib/cmm/fileupload/FileUploadController.java index 0b39fdd3..7b169677 100644 --- a/src/main/java/nlib/cmm/fileupload/FileUploadController.java +++ b/src/main/java/nlib/cmm/fileupload/FileUploadController.java @@ -2,87 +2,185 @@ package nlib.cmm.fileupload; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + import egovframework.com.cmm.EgovWebUtil; import egovframework.com.cmm.service.FileVO; +import nlib.cmm.exception.ErrorMessage; +import nlib.cmm.service.NlibProperty; +import nlib.util.FileUtil; +import nlib.util.StringUtil; import nlib.util.UUID; +/** + *
+ * @Class Name : FileUploadController.java
+ * 
+ * @Description : 파일 업로드를 처리하는 컨트롤러  
+ * 
+ * 
+ * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
+ *
+ * 
+ * + * @ ------------ -------- --------------------------- + * @ 수정일 수정자 수정내용 + * @ ------------ -------- --------------------------- + * @ 2021. 7. 15. KNKIM 최초 생성 + * + * + * @author 이씨플라자 * DIGITALSHIP KNKIM + * @since 2021. 7. 15. + * @version 1.0 + * + */ @Controller public class FileUploadController { - private final Logger log = LoggerFactory.getLogger(FileUploadController.class); + private static final Logger log = LoggerFactory.getLogger(FileUploadController.class); - @RequestMapping("/fileupload/uploadFile.do") - public String uploadFile(final MultipartHttpServletRequest multiRequest - , ModelMap model) throws Exception { + @Resource(name="nlibProperty") + NlibProperty nlibProperty; + + + /** + * 첨부파일이 저장되는 최상위 위치 + */ + @Value("#{properties['fileupload.base.path']}") + private String FILEUPLOAD_BASE_PATH; + + /** + * 첨부파일 임시 저장 위치 + */ + @Value("#{properties['fileupload.temp.subpath']}") + private String FILEUPLOAD_TEMP_SUBPATH; + + @ResponseBody + @RequestMapping(value="/fileupload/uploadFilesAjax.do", produces="application/json") + public ResponseEntity uploadFilesAjax( + final MultipartHttpServletRequest multiRequest + , @RequestParam("subPathKey") String subPathKey + , HttpServletResponse response) { - final Map files = multiRequest.getFileMap(); - if(!files.isEmpty()) { + // TODO : 권한 체크 추가할 것 + + List result = new ArrayList(); + + try { + + // 최상위 위치 + if(FileUtil.isNotValid(FILEUPLOAD_BASE_PATH)) throw new Exception("첨부파일이 저장되는 최상위 위치값이 적절하지 않습니다."); - Iterator> itr = files.entrySet().iterator(); - MultipartFile file; - String filePath = ""; - List result = new ArrayList(); - FileVO fvo; - - int fileKey = 1; - while (itr.hasNext()) { - Entry entry = itr.next(); - - file = entry.getValue(); - String orginFileName = file.getOriginalFilename(); - - //-------------------------------------- - // 원 파일명이 없는 경우 처리 - // (첨부가 되지 않은 input file type) - //-------------------------------------- - if ("".equals(orginFileName)) { - continue; - } - ////------------------------------------ - - int index = orginFileName.lastIndexOf("."); - //String fileName = orginFileName.substring(0, index); - String fileExt = orginFileName.substring(index + 1); - //String newName = KeyStr + getTimeStamp() + fileKey; - String newName = UUID.getPhysicalFileName(); - long size = file.getSize(); + // 서브 위치 + if(StringUtil.isEmpty(subPathKey)) throw new Exception("첨부파일이 저장되는 위치정보값이 정확하지 않습니다."); + String subPath = nlibProperty.getProperty(subPathKey); + if(FileUtil.isNotValid(subPath)) throw new Exception("첨부파일 서브 위치값이 적절하지 않습니다."); + + final Map files = multiRequest.getFileMap(); + log.debug("uploadFilesAjax : 진입 " + (files == null ? " files null " : files.size())); + + File dir = new File(FILEUPLOAD_BASE_PATH + subPath); + if(!dir.exists() || !dir.isDirectory()) dir.mkdirs(); + + if(!files.isEmpty()) { - log.debug("FILE UPLOAD : File New Name=" + newName); - - if (!"".equals(orginFileName)) { - filePath = "c:/temp/data" + File.separator + newName; - file.transferTo(new File(EgovWebUtil.filePathBlackList(filePath))); - } + Iterator> itr = files.entrySet().iterator(); + MultipartFile file; + String filePath = ""; + FileVO fvo; - fvo = new FileVO(); - fvo.setFileExtsn(fileExt); - //fvo.setFileStreCours(storePathString); - fvo.setFileMg(Long.toString(size)); - fvo.setOrignlFileNm(orginFileName); - fvo.setStreFileNm(newName); - //fvo.setAtchFileId(atchFileIdString); - fvo.setFileSn(String.valueOf(fileKey)); + int fileKey = 1; + while (itr.hasNext()) { + Entry entry = itr.next(); - result.add(fvo); + file = entry.getValue(); + String orginFileName = file.getOriginalFilename(); - fileKey++; + //-------------------------------------- + // 원 파일명이 없는 경우 처리 + // (첨부가 되지 않은 input file type) + //-------------------------------------- + if ("".equals(orginFileName)) { + continue; + } + ////------------------------------------ + + int index = orginFileName.lastIndexOf("."); + //String fileName = orginFileName.substring(0, index); + String fileExt = orginFileName.substring(index + 1); + //String newName = KeyStr + getTimeStamp() + fileKey; + String newName = UUID.getPhysicalFileName(); + long size = file.getSize(); + + log.debug("FILE UPLOAD : File New Name=" + newName); + + if (!"".equals(orginFileName)) { + filePath = FILEUPLOAD_BASE_PATH + subPath + "/" + newName; + log.debug("FILE UPLOAD : filePath=" + filePath); + + file.transferTo(new File(EgovWebUtil.filePathBlackList(filePath))); + } + + fvo = new FileVO(); + fvo.setFileExtsn(fileExt); + //fvo.setFileStreCours(storePathString); + fvo.setFileMg(Long.toString(size)); + fvo.setOrignlFileNm(orginFileName); + fvo.setStreFileNm(newName); + //fvo.setAtchFileId(atchFileIdString); + fvo.setFileSn(String.valueOf(fileKey)); + + result.add(fvo); + + fileKey++; + } } + } catch(Exception e) { + ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다 : " + e.toString()); + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage); + } + + // Convert Json + ObjectMapper mapper = new ObjectMapper(); + String json; + try { + json = mapper.writeValueAsString(result); + log.debug("RETURN DATA > json:" + json); + } catch (JsonProcessingException e) { + json = null; + e.printStackTrace(); } - return null; + HttpHeaders responseHeaders = new HttpHeaders(); + //responseHeaders.set("Content-Type", "application/json; charset=UTF-8"); + + ResponseEntity ret = ResponseEntity.ok().headers(responseHeaders).body(json); + return ret; } } + diff --git a/src/main/java/nlib/security/SpringSecurityConfig.java b/src/main/java/nlib/security/SpringSecurityConfig.java index e206b453..2a19a9f9 100644 --- a/src/main/java/nlib/security/SpringSecurityConfig.java +++ b/src/main/java/nlib/security/SpringSecurityConfig.java @@ -52,6 +52,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/js/**") .antMatchers("/temp/**") .antMatchers("/favicon/**") + .antMatchers("/*/*Ajax.do") ; } diff --git a/src/main/java/nlib/util/FileUtil.java b/src/main/java/nlib/util/FileUtil.java new file mode 100644 index 00000000..027dcf30 --- /dev/null +++ b/src/main/java/nlib/util/FileUtil.java @@ -0,0 +1,53 @@ +package nlib.util; + +import egovframework.com.utl.fcc.service.EgovStringUtil; + +/** + *
+ * @Class Name : FileUtil.java
+ * 
+ * @Description : 파일 처리관련 유틸리티 기능 모음 클래스 
+ * 
+ * 
+ * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
+ *
+ * 
+ * + * @ ------------ -------- --------------------------- + * @ 수정일 수정자 수정내용 + * @ ------------ -------- --------------------------- + * @ 2021. 7. 16. KNKIM 최초 생성 + * + * + * @author 이씨플라자 * DIGITALSHIP KNKIM + * @since 2021. 7. 16. + * @version 1.0 + * + */ +public class FileUtil extends EgovStringUtil { + + /** + * 경로나 파일명으로 적합한지를 판단한다. + * + * @param path + * @return 적합한 경우, true + */ + public static boolean isValid(String pathOrFilename) { + if(pathOrFilename == null || pathOrFilename.trim().length() == 0) return false; + + if(pathOrFilename.contains("..")) return false; + + return true; + } + + /** + * 경로나 파일명으로 적합한지를 판단한다. + * + * @param path + * @return 부적합한 경우, true + */ + public static boolean isNotValid(String pathOrFilename) { + return !isValid(pathOrFilename); + } + +} diff --git a/src/main/resources/nlib/nlib.properties b/src/main/resources/nlib/nlib.properties index 6a69e32b..dc0fd3be 100644 --- a/src/main/resources/nlib/nlib.properties +++ b/src/main/resources/nlib/nlib.properties @@ -33,3 +33,16 @@ dataapi.temp.xml.path = C:/iams/workspace/nlib/data/dataxml # Aria \uc54c\uace0\ub9ac\uc998 crypto.aria.defaultKey = TheFederationOfKoreaCultureCenter027042322 + +#---------------------------------------- +# \ucca8\ubd80\ud30c\uc77c \uacbd\ub85c \uc815\ubcf4 +#---------------------------------------- +# \ucca8\ubd80\ud30c\uc77c \ucd5c\uc0c1\uc704 \uc704\uce58 +fileupload.base.path = C:/iams/workspace/nlib/data/fileupload + +# \uc784\uc2dc \uc800\uc7a5 \uc704\uce58 +fileupload.temp.subpath = /temp + +# \ubb3b\uace0\ub2f5\ud558\uae30 \uac8c\uc2dc\ud310 \uc11c\ube0c\uc704\uce58 : \ucca8\ubd80\ud30c\uc77c \ucd5c\uc0c1\uc704 \uc704\uce58 \uc774\ud558\uc758 \uc704\uce58 \uc815\ubcf4\ub97c \uc124\uc815 +fileupload.bbs.qna.subpath = /bbs/qna + diff --git a/src/main/webapp/WEB-INF/jsp/nlib/board/insertQnAForm.jsp b/src/main/webapp/WEB-INF/jsp/nlib/board/insertQnAForm.jsp index 8575fe2f..40f7b7fb 100644 --- a/src/main/webapp/WEB-INF/jsp/nlib/board/insertQnAForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/nlib/board/insertQnAForm.jsp @@ -30,17 +30,21 @@ <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" %> + 묻고답하기 - 글쓰기 + +

${pageTitle }

+ + + action="${pageContext.request.contextPath}/board/insertQnA.do" + method="post"> @@ -60,7 +64,8 @@ - + + @@ -72,19 +77,13 @@ onclick="javascript:fileUploadNow();" /> - - - - - -
+ class="dropzone needsclick" id="myDropzone" name="myDropzone">

이곳에 파일을 끌어다 놓거나, 클릭하여 올릴 파일을 선택하세요. @@ -92,30 +91,31 @@
- diff --git a/src/main/webapp/WEB-INF/jsp/nlib/board/listNotices.jsp b/src/main/webapp/WEB-INF/jsp/nlib/board/listNotices.jsp index cff583a2..f02fa151 100644 --- a/src/main/webapp/WEB-INF/jsp/nlib/board/listNotices.jsp +++ b/src/main/webapp/WEB-INF/jsp/nlib/board/listNotices.jsp @@ -1,9 +1,9 @@ <% /** *
- * @Class Name : getSampleInfo.jsp
+ * @Class Name : listNotices.jsp
  * 
- * @Description : RESTful API 호출 샘플
+ * @Description : JS-GRID 샘플 화면 
  * 
  * 
  * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
@@ -30,7 +30,8 @@
 <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
 <%@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" %>
-QRCode 회원정보
+
+공지사항
 
 
 
@@ -41,11 +42,10 @@
 
 
 
+
 
 
 
-
-
 
+
 // 그리드 데이터 
 var clients = [
     { "noticeNo": 1, "noticeType": "01", "title": "공지사항 제목입니다.", "readCount": 7, "regDate": "2021-07-11" },
diff --git a/src/main/webapp/WEB-INF/tiles/inc/menu.jsp b/src/main/webapp/WEB-INF/tiles/inc/menu.jsp
index 88833be9..a5fdb464 100644
--- a/src/main/webapp/WEB-INF/tiles/inc/menu.jsp
+++ b/src/main/webapp/WEB-INF/tiles/inc/menu.jsp
@@ -25,6 +25,7 @@
     
  • 통신API
  • QR코드
  • 암호화
  • +
  • 프로퍼티갱신
  • 내용
    첨부파일