프로젝트를 수행하면서 파일 업로드는 다양한 방식으로 개발이 가능하다.
파일 업로드 시 업로드할 파일을 Drag and Drop 방식으로 File을 브라우저에 첨부한 후 업로드하는 방식에 대해 설명하고자 한다.
인터넷을 검색하면 Drag and Drop의 다양한 파일 업로드 방식이 있으나, 적용 시 손쉽게 적용할 수 있는 방법을 소개한다.
먼저 파일을 업로드하는 Jsp파일이다.
■ fileUpload.jsp 전체 소스
<html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> <style> #dragandrophandler { border:2px dotted #0B85A1; width:400px; color:#92AAB0; text-align:left;vertical-align:middle; padding:10px 10px 10 10px; margin-bottom:10px; font-size:200%; } .progressBar { width: 200px; height: 22px; border: 1px solid #ddd; border-radius: 5px; overflow: hidden; display:inline-block; margin:0px 10px 5px 5px; vertical-align:top; }
.progressBar div { height: 100%; color: #fff; text-align: right; line-height: 22px; /* same as #progressBar height if we want text middle aligned */ width: 0; background-color: #0ba1b5; border-radius: 3px; } .statusbar { border-top:1px solid #A9CCD1; min-height:25px; width:700px; padding:10px 10px 0px 10px; vertical-align:top; } .statusbar:nth-child(odd){ background:#EBEFF0; } .filename { display:inline-block; vertical-align:top; width:250px; } .filesize { display:inline-block; vertical-align:top; color:#30693D; width:100px; margin-left:10px; margin-right:5px; } .abort{ background-color:#A8352F; -moz-border-radius:4px; -webkit-border-radius:4px; border-radius:4px;display:inline-block; color:#fff; font-family:arial;font-size:13px;font-weight:normal; padding:4px 15px; cursor:pointer; vertical-align:top } </style> <script> var arrStatus = []; var formDatas = []; $(document).ready(function() { var obj = $("#dragandrophandler"); obj.on('dragenter', function (e) { e.stopPropagation(); e.preventDefault(); $(this).css('border', '2px solid #0B85A1'); }); obj.on('dragover', function (e) { e.stopPropagation(); e.preventDefault(); }); obj.on('drop', function (e) {
$(this).css('border', '2px dotted #0B85A1'); e.preventDefault(); var files = e.originalEvent.dataTransfer.files;
//We need to send dropped files to Server handleFileUpload(files,obj); }); $(document).on('dragenter', function (e) { e.stopPropagation(); e.preventDefault(); }); $(document).on('dragover', function (e) { e.stopPropagation(); e.preventDefault(); obj.css('border', '2px dotted #0B85A1'); }); $(document).on('drop', function (e) { e.stopPropagation(); e.preventDefault(); });
$("#upload").click(function(e){ e.preventDefault(); alert("send file to server"); for (var i = 0; i < arrStatus.length; i++) { debugger; sendFileToServer(formDatas[i], arrStatus[i]);
}
}); });
function sendFileToServer(formData,status) {
var uploadURL ="http://localhost:8080/sample/fileupload.do"; //Upload URL var extraData ={path:"d:/temp/files", }; //Extra Data. formData.append("path", "d:/temp/files"); formData.append("saveName", "log_org.zip");
debugger; var jqXHR=$.ajax({ xhr: function() { var xhrobj = $.ajaxSettings.xhr(); if (xhrobj.upload) { xhrobj.upload.addEventListener('progress', function(event) { var percent = 0; var position = event.loaded || event.position; var total = event.total; if (event.lengthComputable) { percent = Math.ceil(position / total * 100); } //Set progress status.setProgress(percent); }, false); } return xhrobj; }, url: uploadURL, type: "POST", contentType:false, processData: false, cache: false, data: formData, success: function(data){ status.setProgress(100);
$("#status1").append("File upload Done<br>"); } });
status.setAbort(jqXHR); }
var rowCount=0; function createStatusbar(obj) { rowCount++; var row="odd"; if(rowCount %2 ==0) row ="even"; this.statusbar = $("<div class='statusbar "+row+"'></div>"); this.filename = $("<div class='filename'></div>").appendTo(this.statusbar); this.size = $("<div class='filesize'></div>").appendTo(this.statusbar); this.progressBar = $("<div class='progressBar'><div></div></div>").appendTo(this.statusbar); this.abort = $("<div class='abort'>Abort</div>").appendTo(this.statusbar); obj.after(this.statusbar);
this.setFileNameSize = function(name,size) { var sizeStr=""; var sizeKB = size/1024; if(parseInt(sizeKB) > 1024) { var sizeMB = sizeKB/1024; sizeStr = sizeMB.toFixed(2)+" MB"; } else { sizeStr = sizeKB.toFixed(2)+" KB"; }
this.filename.html(name); this.size.html(sizeStr); } this.setProgress = function(progress) { var progressBarWidth =progress*this.progressBar.width()/ 100; this.progressBar.find('div').animate({ width: progressBarWidth }, 10).html(progress + "% "); if(parseInt(progress) >= 100) { this.abort.hide(); } } this.setAbort = function(jqxhr) { var sb = this.statusbar; this.abort.click(function() { jqxhr.abort(); sb.hide(); }); } } function handleFileUpload(files,obj) { for (var i = 0; i < files.length; i++) { //FormData var fd = new FormData(); fd.append('file', files[i]); formDatas[i] = fd;
//Status bar var status = new createStatusbar(obj); //Using this we can set progress. status.setFileNameSize(files[i].name,files[i].size); arrStatus[i] = status; //sendFileToServer(fd,status);
} } </script> </head>
<body> <div id="dragandrophandler">Drag & Drop Files Here</div> <br><br> <div> <button type="button" id="upload" name="upload">upload</button> </div> <div id="status1"></div> </body> </html> |
Drag and Drop으로 파일 업로드하는 두가지 방식이 있다.
인터넷을 검색하여 찾은 소스는 파일 선택 시 바로 업로드 하게 되어 있는데 변경한 방식은 UPLOAD 버튼을 선택 시 파일을 업로드 하게 재구성하였다.
Script의 handleFileUpload의 FormData와 status객체를 생성하여 sendFileToServer function을 바로 호출하면 파일을 Drag and Drop이 완료된 후 바로 파일을 업로드 한다.
■ Drag & Drop 시 서버로 파일 전송
function handleFileUpload(files,obj) { for (var i = 0; i < files.length; i++) { var fd = new FormData(); fd.append('file', files[i]);
//Status bar var status = new createStatusbar(obj); //Using this we can set progress. status.setFileNameSize(files[i].name,files[i].size); sendFileToServer(fd,status);
} } |
그러나 업무상으로 File을 Drag & Drop으로 첨부한 후 upload 버튼을 선택 시 파일을 서버로 전송하고자 하는 경우에는 Array Object를 생성하여 FormData와 status를 Array Object에 저장한 후 Upload 버튼 선택 시 파일을 업로드할 수 있다.
■ Drag & Drop 파일 객체 저장 방식
function handleFileUpload(files,obj) { for (var i = 0; i < files.length; i++) { //FormData var fd = new FormData(); fd.append('file', files[i]); formDatas[i] = fd;
//Status bar var status = new createStatusbar(obj); //Using this we can set progress. status.setFileNameSize(files[i].name,files[i].size); arrStatus[i] = status;
} } |
■ upload 버튼 Click 시 파일 전송
$("#upload").click(function(e){ e.preventDefault(); alert("send file to server"); for (var i = 0; i < arrStatus.length; i++) { debugger; sendFileToServer(formDatas[i], arrStatus[i]);
}
|
파일을 업로드 할 때 추가적인 정보를 같이 넘겨주는 경우가 있는데 파일을 저장하기 위해 FormData 객체를 사용하고 있기 때문에 FormData 의 append method를 이용하여 추가적인 정보를 같이 전달할 수 있다.
function sendFileToServer(formData,status) {
var uploadURL ="http://localhost:8080/sample/fileupload.do"; //Upload URL var extraData ={path:"d:/temp/files", }; //Extra Data. formData.append("path", "d:/temp/files"); formData.append("saveName", "log_org.zip");
|
다음은 서버 프로그램이다.
먼저 Fileupload 화면을 보여주는 Controller이다.
@RequestMapping(value="/sample/filePageView.do") public ModelAndView filePageView() throws Exception {
ModelAndView mav = new ModelAndView(); mav.setViewName("fileUpload"); return mav; } |
ModelAndView 객체를 생성하여 fileUpload.jsp를 browser에 보여준다.
파일을 업로드하는 Controller이다.
@RequestMapping(value="/sample/fileupload.do", method = RequestMethod.POST) public @ResponseBody LinkedList<Map<String, Object>> upload(MultipartHttpServletRequest request, HttpServletResponse response, String path, String saveName) {
//1. build an iterator Iterator<String> itr = request.getFileNames(); MultipartFile mpf = null;
LinkedList<Map<String, Object>> files = new LinkedList<Map<String, Object>>(); //2. get each file while(itr.hasNext()){
//2.1 get next MultipartFile mpf = request.getFile(itr.next()); LOGGER.debug(mpf.getOriginalFilename() +" uploaded! "+ files.size());
//2.3 create new fileMeta Map<String, Object> fileMeta = new HashMap<String, Object>(); fileMeta.put("fileName", mpf.getOriginalFilename()); fileMeta.put("fileSize", mpf.getSize()/1024+" Kb"); fileMeta.put("fileType", mpf.getContentType()); // try { // fileMeta.setBytes(mpf.getBytes());
// copy file to local disk (make sure the path "e.g. D:/temp/files" exists) FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream("D:/temp/files/"+mpf.getOriginalFilename()));
} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //2.4 add to files files.add(fileMeta); } // result will be like this // [{"fileName":"app_engine-85x77.png","fileSize":"8 Kb","fileType":"image/png"},...] return files; } |
Chrome과 IE 11버전에서 정상적으로 실행되는것을 확인하였다.
'Spring Framrwork' 카테고리의 다른 글
Spring framework Property Reload (0) | 2018.04.13 |
---|---|
Mybatis include sql (0) | 2018.03.23 |
Spring framework XML Marshaller( Jaxb2Marshaller ) (0) | 2018.03.09 |
spring framework interceptor (0) | 2018.03.02 |
Google Map javascript API 사용법 (0) | 2018.02.07 |