파이어폭스에서는 파일업로드를 드래그앤드롭으로 할 수 있습니다.
3.6 버전에서부터 지원했던 것 같습니다.
자바스크립트와 Spring 프레임워크를 사용해서 간단하게 파일 업로드 프로그램을 작성해 보았습니다.
HTML + JavaScript 업로드 구현부분 UI
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>파일업로드</title> </head> <body> <form name="form0" action="file/upload" method="POST" enctype="multipart/form-data"> <ul> <li>파일 하나 업로드 : <input id="file1" type="file" name="file" /></li> <li>여러 파일 업로드 : <input id="file2" type="file" name="multifile" multiple /></li> <li>파일을 선택하고 '전송'을 눌러 업로드하시거나, 탐색기에서 파일을 드래그앤드롭하여 업로드할 수 있습니다. 드래그앤드롭은 '전송'을 누르는 것이 아니라 드롭시점에 바로 업로드됩니다.</li> </ul> <input type="submit" value="전송"/> </form> <script type="text/javascript"> var dropzone1 = document.getElementById('file1'); var dropzone2 = document.getElementById('file2'); setDnDhandler(dropzone1); setDnDhandler(dropzone2); function setDnDhandler(obj) { obj.addEventListener("dragover", function(event) { event.preventDefault(); }, true); obj.addEventListener("drop", function(event) { event.preventDefault(); var allTheFiles = event.dataTransfer.files; for (var i=0; i<allTheFiles.length; i++) { var element = document.createElement('div'); element.id = 'f' + i; document.body.appendChild(element); sendFile(allTheFiles[i], element.id); } }, true); } function sendFile(file, fileId) { var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function(e) { if (e.lengthComputable) { var percentage = Math.round((e.loaded * 100) / e.total); document.getElementById(fileId).innerHTML = file.name + ' - ' + percentage + '%'; } }, false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } }; xhr.upload.addEventListener("load", function(e){ document.getElementById(fileId).innerHTML = file.name + ' - uploaded'; }, false); xhr.open("POST", "file/upload"); var fd = new FormData(); fd.append("file", file); xhr.send(fd); } </script> </body> </html>
드래그앤드롭을 사용할 때, 드롭될 영역의 경우는 input형이 아니라도 가능하지만, 일반 HTML전송도 가능하게 예제를 작성하고자 input을 사용하였습니다.
드래그앤드롭을 지원하는 부분은 addEventListener 부분입니다. “dragover”, “drop” 이벤트에 대하여 기본동작을 막고, 자바스크립트처리를 할 수 있도록 하였습니다.
파이어폭스에서 input에 type이 file이면, 기본동작이 파일이 업로드를 위해 준비됩니다. IE의 경우는 그 동작조차 없으며, 파일 열기가 수행되지요.
drop이벤트에서 XMLHttpRequest를 통해 AJAX업로드를 합니다.
“xhr.upload.addEventListener(“progress”, …);” 부분은 업로드 처리 경과를 확인할 수 있는 기능입니다. 업로드된 양을 퍼센트로 출력해 줍니다.
서버에서 파일 받기
package test.control; import java.io.File; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @Controller @RequestMapping("/file") public class FileController { @RequestMapping("upload") public @ResponseBody String upload(HttpServletRequest request, HttpServletResponse response) throws IOException { if (! (request instanceof MultipartHttpServletRequest)) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Expected multipart request"); return null; } MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; for ( String fileName : multipartRequest.getFileMap().keySet() ) { for ( MultipartFile file : multipartRequest.getFiles(fileName) ) { String originalFileName = file.getOriginalFilename(); File destination = File.createTempFile("file", originalFileName, new File("/var/dgkim")); } } return "success"; } }
스프링 MVC 프레임워크를 통해, 저수준의 파일 처리부분은 빠지고 실제 파일명과 File객체 처리를 바로 할 수 있습니다.
위 예에서는 의미없이 임시 파일만 생성했으나, 필요에 따라 처리를 작성할 수 있겠습니다.
서버측 라이브러리는 Maven으로 관리하였으며, Spring 3.0외에 추가로 아래 의존성이 있습니다.
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.3</version> </dependency>
소스 다운로드 : http://www.dgkim.net/dav/users/dgkim/fileuptest.zip
참조
- mozilla.or.kr http://hacks.mozilla.or.kr/2011/01/html5-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%8D%94-%EA%B0%9C%EB%B0%9C-%EB%B0%A9%EB%B2%95/
- mozilla.org https://developer.mozilla.org/en/using_files_from_web_applications
- mozilla.org http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/
- toriworks.tistory.com http://toriworks.tistory.com/31