1. 코스 개요
웹 응용 프로그램 시스템의 개발에서 파일 업로드 기능은 매우 일반적인 기능입니다. 오늘날 주로 Javaweb에서 파일 업로드 기능의 관련 기술 구현에 대해 이야기합시다. 인터넷 기술의 빠른 개발로 인해 웹 사이트에 대한 사용자의 경험 요구 사항이 점점 높아지고 있습니다. 비동기 업로드, 드래그 앤 드롭 업로드, 페이스트 업로드, 업로드 진행 모니터링, 파일 썸네일, 대형 파일 브레이크 포인트 연속 전송, 큰 파일 인스턴트 전송 등과 같은 파일 업로드 기능 기술에는 많은 혁신적인 포인트가 있습니다.
이 과정에 필요한 기본 사항 :
기본 HTTP 프로토콜 컨텐츠를 이해하십시오
기본 IO 스트림 작동 기술
서블릿의 기본 사항
JavaScript/JQuery 기술에 대한 기본 지식
2. 파일 업로드의 기본 사항
파일 업로드의 경우 브라우저는 업로드 프로세스 중에 스트림 형태로 파일을 서버 측에 제출하고 모든 스트리밍 데이터는 HTTP 요청과 함께 서버 측로 운반됩니다. 따라서 파일을 업로드 할 때 요청 된 컨텐츠의 형식을 기본적으로 이해해야합니다.
파일 업로드 페이지 :
<form action = "/itheimaupload/uploadservlet"method "method ="post "enctype ="multipart/form-data "> 업로드 된 파일을 선택하십시오 : <input type ="file "name ="첨부 "/> <br/> <입력 유형 ="제출 "value ="제출 "/> </form>
HTTP 요청 컨텐츠 :
3. Java 배경은 서블릿을 사용하여 파일을 수신합니다
서블릿을 사용하여 업로드 된 파일의 입력 스트림을 얻은 다음 요청 매개 변수를 구문 분석하는 경우 문제가됩니다. 따라서 일반적으로 배경은 Apache의 오픈 소스 도구 인 Common-FileUpload 파일 업로드 구성 요소를 사용하기로 선택합니다.
// Java 배경 코드 : Commons-FileUpload 구성 요소 업로드 파일 공개 클래스 업로드 httpservlet {public void doget (httpservletrequest request, httpservletreponse 응답) servletexception, ioexception {// 1. 캐시 DiskFileItemFactory Factory = New DiskFileItemFactory (1*1024*1024, 새 파일 ( "C :/Tempfiles/")); // 2를 구성하십시오. ServleFileUpload 객체 ServletFileUpload SFU = New ServletFileUpload (Factory); // 파일 이름 SFU.SetheAderEncoding ( "UTF-8")의 중국 문제를 해결합니다. // 3. 시도 {list <fileitem> list = sfu.parserequest (request); // 모든 컨텐츠 If (list! = null) {for (fileItem item : list) {// if (item.isformfield ()) {// 정상 양식 매개 변수 // 양식 fieldname get the form fieldname get the form fieldname get the form fieldname get the form get the form get the form get the form get the form stringname value = item.getString ( "UTF-8"); } else {// file if (item.getName ()! = null &&! item.getName (). equals ( "") {// 서버에 저장 하드 디스크 파일 utils.copyInputStreamTofile (), 새 파일 ( "c :/targetFiles/"+item.get ())); (fileUploadeXception e) {e.printstacktrace ();}} public void dopost (httpservletrequest request, httpservletreponse 응답) servletexception, ioexception {doget (요청, 응답);}}4. WebUploader를 사용하여 구성 요소를 업로드하십시오
파일 업로드 페이지의 앞쪽 끝에서 Baidu의 오픈 소스 구성 요소 Webuploader와 같은 유용한 업로드 구성 요소를 사용하도록 선택할 수 있습니다. 이 구성 요소는 기본적으로 비동기 업로드, 드래그 앤 드롭 업로드, 업로드를 붙여 넣기, 업로드 진행 모니터링, 파일 썸네일 및 큰 파일 브레이크 포인트와 같은 파일 전송 및 큰 파일 전송과 같은 일일 파일 업로드 기능을 기본적으로 충족 할 수 있습니다.
WebUpload 구성 요소를 다운로드하십시오
http://fex.baidu.com/webuploader/ webupload 공식 웹 사이트에서 webupload 패키지 다운로드
WebUpload 디렉토리 구조 :
기본 파일 업로드 데모 (업로드 진행 포함)
프론트 엔드
1.1 페이지에서 필요한 CSS, JS를 가져옵니다
<link rel = "stylesheet"type = "text/css"href = "$ {pagecontext.request.contextpath} /csss/webuploader.css"> <script type = "text/javaScript"src = "$ {pagecontext.contextPath } /js/jquery-1.10.2.min.js "> </script> <script type ="text/javaScript "src ="$ {pageConText.Request.ContextPath} /js/webuploader.js "> </script>1.2 업로드 페이지 태그를 작성하십시오
<!-업로드 DIV-> <div id = "Uploader"> <!-파일 목록 디스플레이-> <ul id = "FilElist"> </ul> <!-파일 영역을 선택하십시오-> <div id = "FilePicker"> 파일을 클릭하려면 클릭하십시오 </div> </div>
1.3 WebUpload 코드 작성
<script type = "text/javaScript"> // 1. webupload 초기화 및 전역 매개 변수 var uploader = webuploader = webuploader.create ({// flashk 컨트롤 주소 swf : "$ {pagecontext.request.contextpath} /js/uploader.swf", // 백엔드 제출 서버 : "$ {pagecontext.request.context}/uploxtextppath" 선택 : "#FilePicker", // 자동 업로드 파일 자동 : true,}); // 2. 파일을 선택한 후 파일 정보 큐 디스플레이 // 파일 queued 이벤트 등록 : 파일이 큐에 추가 될 때 트리거/파일 : 현재 선택된 파일 업 로더를 나타냅니다. class = 'fileInfo'> <span> "+file.name+"</span> <div class = 'state'> 업로드 대기 ... </div> <span class = 'text'> </span> </div> ";}); // 3. 업로드 진행 상황 듣기 // 파일 : 파일 업로드 // 백분율 : 현재 진행 상황의 비율. 최대 값은 1입니다. 예 : 0.2uploader.on ( "UploadProgress", 함수 (파일, 백분율) {var id = $ ( "#"+file.id); // 업데이트 상태 정보 id.find ( "div.state"); text ( "upload ..."); // 업로드 백분율 업로드 업로드 백분율 업로드 id.find ( "span.text"). 텍스트 (Math.Round (백분율*100)+"%");}); // 4. 등록 및 업로드 청취 // 파일 : 업로드 된 파일 // 응답 : 배경에서 반환 된 데이터, return uploader.on ( "uploadSuccess", function (fille, response) {// 상태 정보 $ ( "#"+file.id) .find ( "div.state"). text ( "uploaded");};2) 백엔드 서블릿 코드
DiskFileItemFactory Factory = New DiskFileItemFactory (); ServletFileUpload SFU = New ServletFileUpload (Factory); SFU.SetHeAderEncoding ( "UTF-8"); try {list <fileItem> items = sfu.parserequest (request); for (items) {if (item) {if (item) {if) else} else {// 파일 정보 // 파일만이 시스템을 저장하고 처리해야한다고 판단합니다. System.out.println ( "수신 파일 이름 :"+item.getName ()); // 배경에서 하드 디스크에 파일을 복사합니다 .CopyInputStreamTofile (item.getInputStream (), 새 파일 (Server+"); 성공적으로 저장 ");}}} catch (fileUploadexception e) {e.printstacktrace ();}이미지 썸네일을 생성합니다
키 포인트 : Call Uploader.makethumb () 메소드를 썸네일을 생성합니다
uploader.on ( "filequeued", function (file) {// 파일 정보 div $ ( "#filleList"). Append ( "<div id = ''"+file.id+" 'class ='fileInfo '> <img/> <span>"+file.name+"</span> <div class ='state '> upload를 기다리고 있습니다. </div> <span class = 'text'> </span> </div> "); // 이미지 썸네일 만들기 : call makethumb () 메소드 // error : 썸네일을 만들지 못했습니다. // src : 썸네일 업 로더의 경로 (file, function, src) {var id = $ ("#"+file.id); if (error) {id.find ( "img"). replaceWith ( "미리보기");} // 성공하면 지정된 위치 id.find ( "IMG")에 표시됩니다 ( "SRC", SRC);드래그, 붙여 넣기 및 업로드
1) 페이지의 드래그 영역에 DIV를 추가하십시오.
<!-Div-> <div id = "Uploader"> <!-파일 드래그 영역-> <div id = "dndarea"> <p> 파일을 직접 여기에 드래그하여 자동으로 업로드 </p> </div> <!-파일 목록 정보 표시-> <ul id = "filElist"> </ul> <!-DIV ID = "DIV ID ="> 클릭 파일을 클릭하십시오.
2) WebUploader의 글로벌 구성 매개 변수에 드래그 앤 드롭 매개 변수 추가
// 1. webupload 초기화 및 전역 매개 변수 var uploader = webuploader = webuploader.create ({// flashk 컨트롤 주소 swf : "$ {pagecontext.request.contextpath} /js/uploader.swf", // 백엔드 제출 서버 : "$ {pagecontext.request.context}/uploxtextppath" 선택 : "#filepicker", // 자동 업로드 파일 자동 : true, // 드래그 앤 드롭 함수 활성화, 드래그 영역 DND를 지정합니다. "#dndarea", // 페이지의 다른 장소에서 드래그 앤 드롭 기능을 비활성화하여 페이지가 직접 파일을 열지 못하도록하지 않으려면 : true // enable paste : "#Uploader"});대형 파일을 청크로 업로드하십시오
1) WebUploader의 글로벌 매개 변수에 블록 업로드 매개 변수 추가
// 1. webupload 초기화 및 전역 매개 변수 var uploader = webuploader = webuploader.create ({// flashk 컨트롤 주소 swf : "$ {pagecontext.request.contextpath} /js/uploader.swf", // 백엔드 제출 서버 : "$ {pagecontext.request.context}/uploxtextppath" 선택 : "#filepicker", // 자동 업로드 파일 자동 : true, // 드래그 앤 드롭 함수 활성화, 드래그 영역 dnd : // "#dndarea", "#dndarea", "#dndarea", "#dndarea", "#dndarea", "#dndarea", 페이지가 다른 장소에서 페이지 드래그 앤 드롭 기능을 비활성화하여 파일이 직접적으로 disableglobaldnd를 열지 못하게 방지합니다. 청크 : true, // 블록 당 // 파일 크기 (기본 5m) 청크 크기 : 5*1024*1024, // 여러 동시 스레드를 열십시오 (기본 3) 스레드 : 3, // 현재 파일을 업로드 할 때 reparenextFile : true});2) 파일 업로드를 위해 3 개의 시점을 모니터링합니다
위의 세 가지 구성을 추가 한 후 파일이 5m를 초과하면 WebUploader가 파일을 백그라운드로 자동 전송합니다.
각 블록 요청에는 정보가 포함됩니다.
청크의 파일 업로드에서 세 가지 중요한 시점을들을 수 있습니다.
사전 파일 : 전 사전에 전화하기 전 호출 : 블록이 있으면 각 블록이 전송되기 전에 애프터 센드 파일을 호출하십시오. 모든 블록이 전송 된 후 호출하십시오. 파일 업로드의 세 시간 포인트를 모니터링합니다 (참고 :이 코드 섹션은 webUploader.create 앞에 배치해야합니다) // 시점 1 :: 모든 블록이 업로드되기 전에 (1. 파일의 고유 한 마크는 계산 될 수 있습니다. 2. 시간 2 : 각각의 배경으로 업로드하는지 여부를 결정할 수 있습니다. Breakpoint Continuous Transmission) // 3 단계 : 모든 청크가 성공적으로 업로드 된 후 (1. 청크 파일의 배경을 병합 할 것인지 알 수 있음) WebUploader.uploader.register ({ "BeforeSendFile": "BeforesendFile", "Beforesend", "After-Send-File": "After thisting" 모든 청크는 BeforeSendfi Le : function () {// 1. 파일의 고유 한 마크를 계산합니다. 배경이 현재 블록을 저장했는지 여부를 요청하십시오. 존재하는 경우 블록 파일을 건너려면 브레이크 포인트 연속 전송 함수}, // 3 단계 : 모든 블록이 성공적으로 업로드 된 후 다음 기능을 호출하십시오 : function () {// 1. 블록으로 업로드되면 모든 블록 파일이 배경을 통해 병합됩니다.});사전 파일 논리 :
// md5file () 메소드를 사용하여 파일의 고유 한 태그를 계산하십시오. //이 함수는 deferredbeforesendfile : function (file)을 수신합니다. 브레이크 포인트 연속 전송 및 두 번째 전송에 사용되는 파일의 고유 한 태그를 계산합니다 (새로운 webuploader.uploader ()). 검색 ... ");}). 그 다음 (function (val) {고유 한 filetag = val; $ ("#"+file.id) .find ("div.state "). text ("성공적으로 얻은 파일 정보 "); // 파일 정보가 성공적으로 얻어 질 때만 다음 작업이 연기됩니다. 배경이 파일을 저장했는지 여부를 요청하십시오. 존재하는 경우 파일이 건너 뜁니다.전직 논리 :
// 현재 파일의 고유 한 태그를 배경으로 보내는 것은 청크 파일을 저장하는 디렉토리를 작성하는 데 사용됩니다. beforeSend : function () {// 현재 파일의 고유 한 태그를 배경에 가져 오는데 사용되는 파일을 작성하는 데 사용되는 디렉토리를 작성하는 데 사용됩니다.3) 배경은 모든 청크 파일을 저장해야합니다
//이 파일의 모든 파일에 대한 디렉토리를 만들고이 파일의 모든 청크 파일을 저장하십시오. // if (chunks! = null) {system.out.println ( "Chunk Processing ..."); // 모든 청크 파일 파일을 저장하기위한 임시 디렉토리를 만듭니다. if (! chunksdir.exists ()) {chunksdir.mkdir ();} if (chunk! = null) {// chunkfile chunkfile = 새 파일 저장 (chunksdir.getPath ()+"+chunk); fileUtils.copyInputStreamTofile (item.getinputStream (),};4) 프론트 데스크는 백엔드가 모든 청크 파일을 병합하도록 알립니다.
// 프론트 데스크는 파일 병합 후에 알림 후에-센드 파일 로직 : afterSendFile : function (file) {// 1. 청크에 업로드 된 경우 배경을 통해 모든 청크 파일을 병합하여 파일을 병합하기 위해 배경을 요청하십시오. $ .ajax ({type : "post", url : "$ {pagecontext.request.contextpath}/uploadcheckservlet? action = mergechunks", data : {// 파일 고유 한 태그 filemd5, // 파일 이름. filename : file.name}, datatype : "json", success : function (response) {alert (alert (response.msg);}});} // 배경 모든 청크 파일을 ( "mergechunks".equals (action) ( "mergechunks".println ( "start merge ..."); filemd5 = "") directory 파일에서 모든 파일을 읽는다 F = 새 파일 (ServerPath+"/"+filemd5); 파일 [] filearray = f.listfiles (새 fileFilter () {// public boolean accept (file pathname) {if (pathname) {) {retory (pathname) {) {retory (pathname) true;}}); // 컬렉션으로 변환하여 목록을 정렬 할 수 있도록 목록 <file> fillelist = new Arraylist <filest (filearray)); // Small에서 Large Collections.sort (filelist, new Comporator <file> () {public int compare (file o1, file o2)) {if (intger.parseint (integer.parse) integer.parseint (o2.getName ())) {return -1;} return 1;}}); 파일 outputFile = new File (ServerPath+"/"+filename); // 파일을 생성 outputFile.createnewFile (); // output stream filechannel futchannel = new FileOutPutStream (OutCeThannel); // Merge Channel (); for (파일 : filleList) {inchannel = new FileInputStream (file) .getChannel (); incannel.transferto (0, inchannel.size (), untchannel); eNcannel.close (); // delete shard file.delete ();} // 폴더 파일 임시 명확한 파일 (deverpath+"/filemd5); if (tempfile.isdirectory () && tempfile.exists ()) {tempfile.delete ();} // outChannel.close (); response.setContentType ( "text/html; charset = utf-8"); respons.getWriter ().큰 파일 브레이크 포인트가 계속됩니다
블록 업로드의 구현에 따라 중단 점 연속 전송을 구현하는 것은 매우 간단합니다! ! !
프론트 엔드 :
// 시간대 2 : 블록 업로드가 있으면이 함수는 각 블록 업로드 전에 호출됩니다. // 블록 : 현재 블록 객체 BeforeSend : function (block) {// 1. 배경이 현재 블록을 저장했는지 여부를 요청하십시오. 존재하는 경우 블록 파일을 건너려면 중단 점 연속 전송 함수 var deferred = webuploader.deferred (); // 배경이 파일 정보를 저장하는지 여부를 요청하십시오. 그것이 저장되면 건너 뜁니다. 그렇지 않은 경우 청크 컨텐츠는 $ .ajax ({type : "post", url : "$ {pagecontext.request.contextpath}/uploadcheckservlet? action = checkchunk", data : {// 현재 청크 스크립트 덩어리 : // chunk 크기, chunk chunk. lock.end-block.start}, datatype : "json", success : success : function (response) {if (response.ifexist) {// 블록을 건너 뛰고 블록을 건너 뛰고, reject ();} else {// 블록이 존재하지 않거나 불완전하고, 블록 내용이 deferred.resolve (); 파일을 저장하는 디렉토리는 this.owner.options.formdata.filemd5 = filemd5; return Deferred.promise (); },무대 뒤에서:
// 청크가 비공개 void checkKunk (httpservletrequest 요청, httpservletrepsonge 응답)가 ioexception, filenotfoundexception {system.out.println ( "Checkchunk ..."); String filemd5 = request.getParameter ( "filemd5"); string parameter ( "chunkk"); request.getParameter ( "chunksize"); 파일 checkfile = 새 파일 (serverPath+"/"+filemd5+"/"+chunk); response.setContentType ( "text/html; charset = utf-8"); // 크기가 (checkfile.exists () && 크기가 일관됩니다. Checkfile.length () == integer.parseint (chunksize)) {response.getWriter (). 쓰기 ( "{/"ifexist/": 1}");} else {respons.getWriter (). 쓰기 ( "{/"ifexist/": 0}")}몇 초 만에 파일 전송
모든 블록 요청 전에 두 번째 전송 기능을 구현할 수 있습니다! ! !
프론트 엔드 :
beforeSendFile : function (file) {// defferedvar deferred = webuploader.deferred (); // 1을 만듭니다. 브레이크 포인트 연속 전송 및 두 번째 전송에 사용되는 파일의 고유 표시를 계산합니다 (새로운 webuploader.uploader ()). val; $ ( "#"+file.id) .find ( "div.state"). 텍스트 ( "파일 정보를 성공적으로 얻었습니다"); $ .ajax ({type : "post", url : "$ {pagecontext.request.contextpath}/uploadcheckservlet? action = filecheck", data : {// 파일의 고유 한 태그 filemd5 : "json", success : function (response) {if (response.ifexist) {$ ( "#"+file.id) .find ( "div.state"). 텍스트 ( "성공적으로 전송 된 경우"); Deferred.resolve ();}}});}); // return deferredreturn.promise (),},무대 뒤에서:
// 파일의 MD5 데이터가 데이터베이스 개인 void filecheck (httpservletrequest request, httpservletResponse 응답)과 관련이 있는지 확인합니다. IoException, filenotFoundException {String Filemd5 = request.getParameter ( "filemd5"); // 데이터베이스 맵 <string, string = new Hashmap <String, String> (); Database.put ( "576018603F4091782B68B78AF85704A1", "01. 코스 review.itcast "); response.setContentType ("text/html; charset = utf-8 "); if (database.containskey (filemd5)) {response.getWriter (). writ위의 내용은 편집자가 귀하에게 소개 한 Javaweb 파일 업로드 및 다운로드에 대한 예제입니다 (Cool 파일 업로드 기술). 모든 사람에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 모든 사람에게 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!