티스토리 뷰
728x90
Spring - Drag & Drop 파일 업로드
출처 : Husk's repository :: 드래그 앤 드롭 파일 업로드 스프링 예제
관련 라이브러리 추가
commons-io-2.4.jar commons-fileupload-1.3.jar
WebContent\WEB-INF\iot-servlet.xml
<!-- ========================= Multipart Form-Data Resolver ========================= --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- max upload size in bytes --> <property name="maxUploadSize" value="20971520" /> <!-- 20MB --> <!-- max size of file in memory (in bytes) --> <property name="maxInMemorySize" value="1048576" /> <!-- 1MB --> </bean>
업로드 jsp (WebContent\WEB-INF\jsp\dragdrop\fileUpload.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page session="false" %> <html> <head> <title>Test</title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.js"></script> <style> .dragAndDropDiv { border: 2px dashed #92AAB0; width: 650px; height: 200px; color: #92AAB0; text-align: center; vertical-align: middle; padding: 10px 0px 10px 10px; font-size:200%; display: table-cell; } .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:99%; 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 type="text/javascript"> $(document).ready(function(){ var objDragAndDrop = $(".dragAndDropDiv"); $(document).on("dragenter",".dragAndDropDiv",function(e){ e.stopPropagation(); e.preventDefault(); $(this).css('border', '2px solid #0B85A1'); }); $(document).on("dragover",".dragAndDropDiv",function(e){ e.stopPropagation(); e.preventDefault(); }); $(document).on("drop",".dragAndDropDiv",function(e){ $(this).css('border', '2px dotted #0B85A1'); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; handleFileUpload(files,objDragAndDrop); }); $(document).on('dragenter', function (e){ e.stopPropagation(); e.preventDefault(); }); $(document).on('dragover', function (e){ e.stopPropagation(); e.preventDefault(); objDragAndDrop.css('border', '2px dotted #0B85A1'); }); $(document).on('drop', function (e){ e.stopPropagation(); e.preventDefault(); }); function handleFileUpload(files,obj) { for (var i = 0; i < files.length; i++) { var fd = new FormData(); fd.append('file', files[i]); var status = new createStatusbar(obj); //Using this we can set progress. status.setFileNameSize(files[i].name,files[i].size); sendFileToServer(fd,status); } } 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'>중지</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 sendFileToServer(formData,status) { var uploadURL = "<c:url value="/dragdrop/fileUpload/post.iot"/>"; //Upload URL var extraData ={}; //Extra Data. 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); } }); </script> </head> <body> <div id="fileUpload" class="dragAndDropDiv">Drag & Drop Files Here</div> </body> </html>
Controller
package com.iot.controller; import java.io.File; import java.util.Iterator; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; /** * Handles requests for the application home page. */ @Controller public class FileUploadDragDropController { @RequestMapping(value = "/dragdrop/fileUpload.iot", method = RequestMethod.GET) public String dragAndDrop(Model model) { return "/dragdrop/fileUpload"; } @RequestMapping(value = "/dragdrop/fileUpload/post.iot") // ajax에서 호출하는 부분 @ResponseBody public String upload(MultipartHttpServletRequest multipartRequest) { // Multipart로 // 받는다. Iterator<String> itr = multipartRequest.getFileNames(); String filePath = "C:/test"; // 설정파일로 뺀다. while (itr.hasNext()) { // 받은 파일들을 모두 돌린다. /* * 기존 주석처리 MultipartFile mpf = multipartRequest.getFile(itr.next()); * String originFileName = mpf.getOriginalFilename(); System.out.println( * "FILE_INFO: "+originFileName); //받은 파일 리스트 출력' */ MultipartFile mpf = multipartRequest.getFile(itr.next()); String originalFilename = mpf.getOriginalFilename(); // 파일명 String fileFullPath = filePath + "/" + originalFilename; // 파일 전체 경로 try { // 파일 저장 mpf.transferTo(new File(fileFullPath)); // 파일저장 실제로는 service에서 처리 System.out.println("originalFilename => " + originalFilename); System.out.println("fileFullPath => " + fileFullPath); } catch (Exception e) { System.out.println("postTempFile_ERROR======>" + fileFullPath); e.printStackTrace(); } } return "success"; } }
업로드된 폴더 웹에서 접근하기
Tomcat 설정파일 server.xml에 <Context docBase="C:/test" path="/test" reloadable="true"/> 를 Host 테그 전에 추가
<Context docBase="C:/test" path="/test" reloadable="true"/> </Host> </Engine> </Service> </Server>
Spring - Drag & Drop 파일 업로드 (img_type, img_id 속성 추가)
한 페이지내에서 여러개의 파일 업로드를 구현하기 위해서 img_type, img_id 속성을 추가해서 여러개의 업로드가 발생하더라고 구분 할 수 있게 구현
html 페이지
<div class="dragAndDropDiv" img_type="uploadarea" img_id="1"> <div class="dragAndDropDiv" img_type="uploadarea" img_id="2">
파일 올려진 경우 이벤트에서 img_type, img_id 속성 가져오기 - javascript
$(document).on("drop",".dragAndDropDiv",function(e){ $(this).css('border', '2px dotted #0B85A1'); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; // img_type, img_id 속성 가져오기 var img_type = $(e.target).attr('img_type'); var img_id = $(e.target).attr('img_id'); handleFileUpload(img_type, img_id, files,objDragAndDrop); });
FormData 구성 img_type, img_id 포함 - javascript
function handleFileUpload(img_type, img_id, files,obj) { for (var i = 0; i < files.length; i++) { var fd = new FormData(); fd.append('img_type', img_type); fd.append('img_id', img_id); fd.append('file', files[i]); var status = undefined; //var status = new createStatusbar(obj); //Using this we can set progress. //status.setFileNameSize(files[i].name,files[i].size); sendFileToServer(fd,status); } }
업로드 완료 처리 - javascript
img_type이 request인 경우 img테그의 src 속성 값 변경 처리
function sendFileToServer(formData,status) { var uploadURL = "<c:url value="/dragdrop/fileUpload/post.do"/>"; //Upload URL ... 생략 ... data: formData, success: function(data) { // 업로드가 완료되면 호출되는 메소드 if (status != undefined) { status.setProgress(100); } // console.log('img_type = ' + data.img_type); console.log('img_id = ' + data.img_id); $.each(data.files, function(index, file) { console.log('filename = ' + file); if (data.img_type=='request') { var targetObj = $(".dragAndDropDiv[img_type='"+data.img_type+"'][img_id='"+data.img_id+"']"); targetObj.attr('src', '/test/' + file); targetObj.attr('uuid', file); } }); } });
javascript 전체
$(document).ready(function() { var objDragAndDrop = $(".dragAndDropDiv"); $(document).on("dragenter",".dragAndDropDiv",function(e){ e.stopPropagation(); e.preventDefault(); $(this).css('border', '2px solid #0B85A1'); }); $(document).on("dragover",".dragAndDropDiv",function(e){ e.stopPropagation(); e.preventDefault(); }); $(document).on("drop",".dragAndDropDiv",function(e){ $(this).css('border', '2px dotted #0B85A1'); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; // img_type, img_id 속성 가져오기 var img_type = $(e.target).attr('img_type'); var img_id = $(e.target).attr('img_id'); handleFileUpload(img_type, img_id, files,objDragAndDrop); }); $(document).on('dragenter', function (e){ e.stopPropagation(); e.preventDefault(); }); $(document).on('dragover', function (e){ e.stopPropagation(); e.preventDefault(); objDragAndDrop.css('border', '2px dotted #0B85A1'); }); $(document).on('drop', function (e){ e.stopPropagation(); e.preventDefault(); }); function handleFileUpload(img_type, img_id, files,obj) { for (var i = 0; i < files.length; i++) { var fd = new FormData(); fd.append('img_type', img_type); fd.append('img_id', img_id); fd.append('file', files[i]); var status = undefined; //var status = new createStatusbar(obj); //Using this we can set progress. //status.setFileNameSize(files[i].name,files[i].size); sendFileToServer(fd,status); } } 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'>중지</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 sendFileToServer(formData,status) { var uploadURL = "<c:url value="/dragdrop/fileUpload/post.do"/>"; //Upload URL var extraData ={}; //Extra Data. 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 if (status != undefined) { status.setProgress(percent); } }, false); } return xhrobj; }, url: uploadURL, type: "POST", dataType : 'json', contentType:false, processData: false, cache: false, data: formData, success: function(data) { // 업로드가 완료되면 호출되는 메소드 if (status != undefined) { status.setProgress(100); } // console.log('img_type = ' + data.img_type); console.log('img_id = ' + data.img_id); $.each(data.files, function(index, file) { console.log('filename = ' + file); if (data.img_type=='request') { var targetObj = $(".dragAndDropDiv[img_type='"+data.img_type+"'][img_id='"+data.img_id+"']"); targetObj.attr('src', '/test/' + file); targetObj.attr('uuid', file); } else { var uploadTbody = $('#uploadTbody'); var row = $('<span style="display : block;"></span>'); row.text(file); uploadTbody.append(row); // 배열 초기화 var uploadFilenames = new Array(9); for (i=0; i<uploadFilenames.length; i++) { uploadFilenames[i] = ''; } var t_fileList = $('#uploadTbody>span'); /* for (i=1; i<=t_fileList.length; i++) { var file_value = $('#uploadTbody>span:nth-child('+i+')'); console.log(i + '/' + file_value.text()); uploadFilenames[i-1] = file_value.text(); } */ console.log(t_fileList.length); $.each( t_fileList, function( key, value ) { console.log( key + ": " + $(value).text() ); uploadFilenames[key] = $(value).text(); }); console.log(uploadFilenames[0]); console.log(uploadFilenames[1]); console.log(uploadFilenames[2]); console.log(uploadFilenames[3]); } }); //$("#status1").append("File upload Done<br>"); } }); if (status != undefined) { status.setAbort(jqXHR); } } });
업로드 메소드
@RequestMapping(value = "/dragdrop/fileUpload/post.do") // ajax에서 호출하는 부분 @ResponseBody public String upload( @RequestParam(value = "img_type", required = false, defaultValue = "") String img_type, @RequestParam(value = "img_id", required = false, defaultValue = "-1") int img_id, MultipartHttpServletRequest multipartRequest) // Multipart로 받는다. { System.out.println("img_type = " + img_type + "/img_id = " + img_id); Iterator<String> itr = multipartRequest.getFileNames(); String filePath = "C:/test"; // 설정파일로 뺀다. String targetFilename = ""; JSONArray filenames = new JSONArray(); while (itr.hasNext()) { // 받은 파일들을 모두 돌린다. /* * 기존 주석처리 MultipartFile mpf = multipartRequest.getFile(itr.next()); * String originFileName = mpf.getOrigin'alFilename(); System.out.println( * "FILE_INFO: "+originFileName); //받은 파일 리스트 출력 */ MultipartFile mpf = multipartRequest.getFile(itr.next()); String originalFilename = mpf.getOriginalFilename(); // 파일명 // 파일 확장자 추출 String fileExt = FileUtils.getFileExt(originalFilename); UUID uuid = UUID.randomUUID(); targetFilename = uuid.toString() + "." + fileExt.toLowerCase(); String fileFullPath = filePath + "/" + targetFilename; // 파일 전체 경로 try { // 파일 저장 mpf.transferTo(new File(fileFullPath)); // 파일저장 실제로는 service에서 처리 System.out.println("originalFilename => " + originalFilename); System.out.println("fileFullPath => " + fileFullPath); } catch (Exception e) { System.out.println("postTempFile_ERROR======>" + fileFullPath); e.printStackTrace(); } filenames.add(targetFilename); } JSONObject jobj = new JSONObject(); jobj.put("img_type", img_type); jobj.put("img_id", img_id); jobj.put("files", filenames); return jobj.toJSONString(); }
댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 일본여행
- 튜닝쇼 2008
- 송주경
- ble
- oracle
- JavaScript
- ubuntu
- Spring MVC
- 레이싱모델 익스트림 포토 페스티벌
- Java
- 전예희
- flex
- Linux
- Mac
- sas2009
- SAS
- 지스타2007
- NDK
- android
- ffmpeg
- 동경
- KOBA
- Spring
- Delphi
- MySQL
- Delphi Tip
- koba2010
- Xcode
- BPI-M4
- 서울오토살롱
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함