최근에 프로젝트에 파일을 업로드해야합니다. 작업을 완료 한 후 공유하고 메모를하십시오.
업로드 기능은 백그라운드 및 Java에서 구현되며 프론트 엔드는 주로 JS의 AJAX에서 구현됩니다. 배경은 또한 정기적으로 삭제할 임시 파일을 추가합니다.
효과는 그림과 같이 나타납니다
우선, 업로드 함수의 주요 클래스 인 다음은 코드입니다.
패키지 util.upload; import java.io.file; import java.io.ioexception; import java.text.simpledateformat; import java.util.date; import java.util.iterator; import java.util.list; import java.util.uuid; import javax.servlet.servletexmence; javax.servlet.http.httpservlet; import javax.servlet.http.htttp.httpervletrequest; import javax.servlet.http.http.httpervletresponse; import javax.servlet.http.httpsession; import org.apache.commons.fileupload.fileupload; org.apache.commons.fileupload.disk.diskfileitemfactory; import org.apache.commons.fileupload.servlet.servletfileupload; public class uploadservlet 확장 httpservlet {private static final long serialversionuid = -3100028422371321159L; 개인 부울 isallowed; 개인 문자열 upfilename; // 합법적 인 접미사 이름으로 배열 정의 개인 string [] alceverextname = new String [] { "zip", "rar", // compress file "txt", "doc", "wps", "docx", "java", // text "xls", "xlsx", // table "ppt", "pptx", // slide "pdf", // "f"JPG ","bmp ","gif ","// picture}; protected void doget (htperververtrected void) httpservletresponse 응답) servletexception, ioexception {dopost (요청, 응답); httpservletrequest request, httpservletreponse 응답) servletexception, ioexception을 설정합니다. response.setCharacterEncoding("utf-8"); //Get session, save progress and upload results, upload starts as nok, when Ok means uploading is completed HttpSession session=request.getSession(); session.setAttribute("result", "nok"); session.setAttribute("error", ""); String error=""; upFileName=""; isAllowed=false; //Set 업로드 된 파일의 최대 값은 100MB int maxsize = 100*1024*1024를 초과하지 않아야합니다. // 파일 업로드 객체 DiskFileItemFactory 팩토리; ServletFileUpload 업로드 = 새로운 ServletFileUpload (공장); // 업로드 리스너 생성 및 설정 리스너 업로드 리스너 리스너 = 새로운 uploadListener (); session.setattribute ( "청취자", 청취자); upload.setprogresslistener (리스너); // 경로 업로드 문자열 경로 = requestSession (). getServletContext (). getRealPath ( "/upload"); 문자열 requestPath = requestSession (). getServletContext (). getContextPath ()+"/Upload"; 파일 dirfile = 새 파일 (Path); //system.out.println(request.getSession (). getServletContext (). getContextPath ()); // 폴더가 존재하지 않으면 if (! dirfile .exists () &&! dirfile .isdirectory ()) {dirfile .mkdir (); } // 날짜를 기준으로 폴더를 생성하고 해당 날짜 날짜 = 새 날짜 ()와 함께 폴더에 저장합니다. simpledateformat sdf = new simpledateformat ( "yyyymmdd"); 문자열 subdirname = sdf.format (날짜); 파일 subdirfile = 새 파일 (path+"/"+subdirname); if (! subdirfile .exists () &&! subdirfile .isdirectory ()) {subdirfile .mkdir (); } try {// Parse Upload 요청 목록 <fileItem> items = upload.parserequest (request); iterator <fileitem> itr = items.iterator (); while (itr.hasnext ()) {fileitem item = (fileitem) itr.next (); // 파일 도메인인지 확인 if (! item.isformfield ()) {if (item.getName ()! = null &&! item.getName (). equals ( "")) {// 업로드 된 파일 크기와 파일 이름 long upFilesize = item.getSize (); 문자열 filename = item.getName (); // 파일 접미사 이름 string [] splitname = filename.split ( "//."); String extName = splitName [splitName.length-1]; // 파일의 접미사 이름을 확인하십시오 (string enver : allendextName) {if (enver.qualsIgnoreCase (extName)) {isallowed = true; }} if (! isallowed) {error = "업로드 파일 형식은 불법입니다!"; 부서지다; } if (upfilesize> maxsize) {error = "업로드 파일이 너무 커서 100MB를 초과하지 않는 파일을 선택하십시오!"; 부서지다; } // 현재 파일은 서버의 메모리에 일시적으로 저장되어 임시 객체 파일 TempFile = 새 파일 (makeFilename (filename))을 구성합니다. // 파일의 디렉토리와 파일 이름을 지정하여 서버 파일을 업로드 파일 = 새 파일 (path+"/"+subdirname+"/", tempfile.getName ()); item.write (파일); // 파일을 쓰는 첫 번째 방법은 UpFilename = requestPath+"/"+subdirname+"/"+tempfile.getName ()입니다. if (upfilename.equals ( "")) {error = "파일을 업로드 할 선택 없음!"; } system.out.println (upfilename); /*// 입력 스트림의 두 번째 쓰기 파일 작성 파일 읽기 파일 inputStream은 = item.getInputStream (); int 길이 = 0; 바이트 [] by = 새로운 바이트 [1024]; fileoutputStream fos = 새 FileOutputStream (file); while (길 //thread.sleep(10); } fos.close (); //thread.sleep(1000); */} else {error = "파일을 업로드 할 선택 없음!"; }}}} catch (예외 e) {e.printstacktrace (); error = "파일을 업로드 할 때 오류가 발생했습니다."+e.getMessage (); } if (! error.equals ( "")) {system.out.println (error); session.setAttribute ( "오류", 오류); } else {session.setAttribute ( "result", "ok"); session.setattribute ( "filename", upfilename); }} / *** 파일 덮어 쓰기를 방지하려면 파일을 업로드하려면 고유 한 파일 이름을 생성해야합니다.* @param filename 원본 파일 이름* @return 생성 된 고유 한 파일 이름* / private string makefilename (string filename) {return uuid.randomuuid (). toString () + " + filename; }} Commons-FileUpload-1.3.1.jar 및 Commons-IO-2.4.jar를 소개해야합니다
업로드 프로세스 중에 실시간으로 업로드 진행 상황과 같은 정보를 얻어야합니다. 소개 된 라이브러리는 우리를 위해 ProgressListener 인터페이스를 추가했습니다. 이 인터페이스를 구현하기 위해 다른 클래스를 작성 하고이 인터페이스를 위의 클래스에 추가합니다.
// 팩토리 객체 및 파일 업로드 객체 만들기 DiskFileItemFactory Factory = New DiskFileItemFactory (); ServletFileUpload 업로드 = 새로운 ServletFileUpload (공장); // 업로드 리스너 생성 및 설정 리스너 업로드 리스너 리스너 = 새로운 uploadListener (); session.setattribute ( "청취자", 청취자); upload.setprogresslistener (리스너);
아래는이 청취 클래스의 특정 구현 코드입니다.
패키지 util.upload; import org.apache.commons.fileupload.progresslistener; public class uploadlistener emprogrowlistener {private volatile long bytesread = 0l, // 업로드 된 bytes contentlength = 0l, // 바이트의 총 수 = 0l; public uploadListener () {super (); } @override public void update (long abytesread, long acontentlength, int anitem) {bytesread = abytesread; contentLength = acontentLength; 항목 = anitem; } public long getbytesread () {return bytesread; } public long getContentLength () {return contentLength; } public long getItem () {반환 항목; }}이제 업로드 진행 상황과 같은 정보를 얻을 수 있지만 여전히 프론트 엔드로 돌아갈 서블릿이 필요합니다. 다음 구현
패키지 util.upload; import java.io.ioexception; import java.io.printwriter; import java.util.hashmap; import java.util.map; import javax.servlet.servletexception; import javax.servlet.http.htttp.httpservlet; import javax.servlet.svervlet.htpterver; javax.servlet.http.http.httervletresponse; import javax.servlet.http.httpsession; import org.apache.commons.fileupload.progresslistener; import com.google.gson.gson;/** 업로드 진행, 오류, 업로드 경로, 업로드 경로, 업로드 경로, 업로드 경로, 업로드 경로, 업로드 경로, 업로드 경로, 업로드 getprogsprogseprogservertends. httpservlet {private static final long serialversionuid = -3596466520775012991L; 보호 된 void doget (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {dopost (요청, 응답); } 보호 된 void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {request.setcharacterencoding ( "utf-8"); 응답 .SetchAracterEncoding ( "UTF-8"); 업로드 리스트너 리스너 = NULL; httpsession session = request.getSession (); 문자열 error = (문자열) session.getAttribute ( "error"); 문자열 결과 = (문자열) session.getAttribute ( "결과"); String filename = (String) session.getAttribute ( "filename"); printwriter out = response.getwriter (); long bytesread = 0, contentlength = 0; if (session! = null) {Listener = (uploadListener) session.getAttribute ( "Listener"); if (Learser == null) {return; } else {bytesread = lareer.getBytesRead (); // 업로드 된 바이트의 수 ContentLength = Listener.getContentLength (); // Total Bytes} // 직접 정의 된 반환 형식은 String rp = BytesRead +"," +contentLength +"," +error +"," +filename; "," +filename; //system.out.println(rp); out.print (RP); /* // return json 형식 데이터 맵 <string, object> map = new Hashmap <String, object> (); map.put ( "BytesRead", BytesRead); map.put ( "contentlength", contentlength); map.put ( "오류", 오류); map.put ( "결과", 결과); map.put ( "filename", filename); GSON GSON = NEW GSON (); 문자열 json = gson.tojson (지도); out.print (json);*/ out.flush (); out.close (); }}}백그라운드에 업로드 된 기능 코드가 작성되었습니다. 다음은 업로드를 구현하는 프론트 엔드입니다.
<! docType html> <html> <head> <meta charset = "utf-8"/> <script type = "text/javaScript"src = "js/upfile.js"charset = "utf-8"> </script> <link rel = "stylesheet"type "text/css"href = "css/upile.cs" <body> <a href = "javaScript : addOne ()"> add </a> <div id = "target"> <input type = "file"id = "file"name "="file "onchange ="addfile (event) ""multure/> </div> <span id = "test"> 0 </span> </html>
인터페이스는 비교적 간단하고 태그 만 추가하면 업로드 된 입력이 숨겨져 있습니다.
CSS 파일 주요 렌더링의 업로드 진행 상황 표시
#file {디스플레이 : 없음; } .pro {너비 : 500px; } .pborder {위치 : 상대; 너비 : 500px; /* 너비*/ 테두리 : 1px 솔리드 #B1D632; 패딩 : 1px; } .DrawPro {너비 : 0px; 디스플레이 : 블록; 위치 : 상대; 배경 : #B1D632; 색상 : #333333; 높이 : 20px; /* 높이*/ 라인 높이 : 20px; /* 텍스트가 수직 중심이되기 전에 높이와 일치해야합니다.*/} .pspan {위치 : 절대; 너비 : 500px; 텍스트 정렬 : 센터; 글꼴 중량 : 대담한; }다음은 프론트 엔드 포커스, JS 파일입니다
// 업로드 정보를 표시하는 htmlvar upfile_html은 '<div> <div>' + '<span> 0%</div> </div> <span name = "path"> </span> <img src = "common/upload/del.png"style = "float"; abortupload (thish)>'; "target"; // 파일을 업로드하기위한 대상 div의 idvar httpxml = null; // xmlhttprequest var httpprogress = null; // xmlhttprequest var var oldfilelist = new array (); array (); // 업로드 된 파일 목록 var f_input; // 파일 var flag = true를 업로드하는 입력 객체를 업로드 할 수 있습니다. 다음 파일 var var uurl = "업로드"; // 파일을 업로드하라는 요청 urlvar gurl = // urlvar cancelflag = 0; // cancel timer; = 0; // 큐로드중인 파일의 idvar ID = 0; 큐에서 마지막 파일의 ID/*** 파일 개체*/function uploadFile (id, file) {this.id = id; this.file = 파일; this.state = 0; this.path = "";}/*** 초기화 메소드*/wind var tdiv = document.getElementById (TargetDiv_id); var oldspan = tdiv.getElementsByTagName ( "span"); for (var i = 0; i <oldspan.length; i ++) {oldfilelist.push (OldSpan [i] .getAttribute ( "name")); }}/** * 업로드 할 파일을 선택하십시오 */function addone () {f_input.value = null; f_input.click ();}/*** 파일을 선택한 후 파일 객체를 큐에 추가하고 업로드를 시작하십시오*/function addfile (evt) {var f = f_input.files [0]; if (f! = undefined) {var uf = new UploadFile (id, f); uplist.push (uf); var div = document.createelement ( "div"); Div.setAttribute ( "id", "pro" + (id)); Div.setAttribute ( "class", "pro"); div.innerhtml = upfile_html; var targetdiv = document.getElementById (TargetDiv_id); TargetDiv. AppendChild (div); div.getElementsByTagName ( "span") [1] .innerHtml = "파일 이름 :" + Uplist [id] .file.name; Waittimer = setInterVal ( "upload ()", 1000); id ++; }}/*** 큐에서 파일을 업로드*/function upload () {if (flag == true) {if (uplist.length> 0) {var uf; for (var i = 0; i <uplist.length; i ++) {if (uplist [i] .state == 0) {uf = uplist [i]; 업 목록 [i] .state = 1; 부서지다; }} if (uf! = undefined & uf! = null) {flag = false; if (wind } else if (wind } var formdata = new FormData (); formdata.append ( "파일", uf.file); httpup.open ( "post", uurl, true); httpup.upload.addeventListener ( 'progress', uploadprogress, false); httpup.send (formdata); nowid = uf.id; TIMER = setInterVal ( "getp ()", 50); }}}}/*** 업로드 진행 상황과 같은 정보 가져옵니다*/function getp () {if (wind } else if (wind } httpProgress.onreadyStateChange = OnProgress; httpprogress.open ( "post", gurl, true); httpprogress.setrequestheader ( "content-type", "application/x-www-form-urlencoded"); httpprogress.send ( "& timestamp =" + (new date ()). gettime ());}/*** 반환 된 업로드 정보를 처리하고 인터페이스에 표시*/function onprogress () {if (httpprogress.cready = 4 && httpprogress.status == 200) var result = result.replace (/(^/s*) | (/s*$)/g, ""); var res = result.split ( ","); var now = parseint (res [0]); var all = parseint (res [1]); var err = res [2]; var state = res [3]; var path = res [4]; var per = (지금 / all * 100) .tofixed (2); var prodiv = document.getElementById ( "pro" + nowid); if (prodiv! = null & prodiv! = undefined) {if (err! = "& err! = null & err.length> 0) {window.clearInterval (타이머); if (cancelflag == 1) {err = "종료 업로드"; cancelflag = 0; } prodiv.getElementsByTagName ( "div") [0] .style.display = "none"; prodiv.getElementsByTagName ( "span") [1] .innerHtml = err; httpup.abort (); flag = true; 업 목록 [nowid] .state = 3; 반품; } if (state == "ok") {prodiv.getElementsByTagName ( "div") [0] .style.display = "none"; var tmpf = 업 목록 [nowid] .file; prodiv.getElementsByTagName ( "span") [1] .innerhtml = "파일 이름 :" + tmpf.name; Window.clearInterval (타이머); flag = true; 업 목록 [nowid] .state = 2; 업 목록 [nowid] .path = 경로; 반품; } prodiv.getElementsByTagName ( "div") [1] .style.width = per * 5 + "px"; prodiv.getElementsByTagName ( "span") [0] .innerHtml = per + "%"; }}}/*** 업로드를 취소하는 메소드*/함수 abortupload (obj) {var idstr = obj.parentnode.id; var id = idstr.slice (3); if (uplist [id] .state == 1) {httpup.abort (); flag = true; cancelflag = 1; } else {uplist [id] .state = 3; } document.getElementById (idstr) .remove ();}/*** 파일을 업로드하는 경로를 가져옵니다* @returns 형식 문자열*/function getFileliststr () {var str = ""; if (oldfilelist.length> 0) {for (var i = 0; i <oldfilelist.length; i ++) {if (oldfilelist [i]! = null & oldfilelist [i]! = "& OldFilelist [i]! = str = str = str = str = str + OldFilEList [i] +"; }}} for (var i = 0; i <uplist.length; i ++) {var f = uplist [i]; if (f.state == 2) {str = str + f.path + ","; }} return str;}/*** 수정 될 때 이미 있던 이전 첨부 파일을 제거하십시오*/function removeold (btn) {var num = btn.getAttribute ( "name"); oldfilelist [num -1] = null; btn.parentnode.remove ();} 함수 uploadprogress (e) {if (e.lengthcomputable) {var ibytesuploaded = e.loaded; var ibytestotal = e.total; document.getElementById ( "test"). innerHtml = iByTesUploaded+"/"+iByTestotal; }} AJAX를 사용하여 업로드 파일을 보내고 업로드 진행, 결과 및 기타 정보를 업로드하십시오.
사용 된 HTML5 파일 API는 IE9 이상이 호환되어야합니다. Firefox에는 문제가 있습니다. AJAX 요청은 즉시 반환되지 않습니다. 모든 AJAX 요청이 전송 될 때까지 동일한 결과가 반환되므로 업로드 진행 상황이 표시되지 않습니다. 그러나 html5 파일 API를 사용하여 작은 코드가 추가되어 있습니다. 페이지 아래의 테스트 div의 값은 프론트 엔드에서 얻은 진행입니다.
업로드 된 모든 파일이 구현 된 다음 업로드 된 임시 파일이 처리됩니다. UUID 명명 된 파일이 사용되므로 많은 파일이 생성되며 쓸모없는 파일은 정기적으로 처리해야합니다. ServletContextListener 사용 :
Servlet API에는 ServletContextListener 인터페이스가 있으며, 실제로 웹 애플리케이션의 수명주기 인 ServletContext 객체의 수명주기를들을 수 있습니다.
서블릿 컨테이너가 웹 애플리케이션을 시작하거나 종료하면 ServletContexTevent 이벤트가 트리거되어 ServletContextListener가 처리합니다. ServletContexTevent 이벤트를 처리하기 위해 ServletContextListener 인터페이스에 두 가지 방법이 정의됩니다.
기능을 사용하여 임시 파일을 정기적으로 삭제하는 기능이 실현됩니다. 코드는 다음과 같습니다.
패키지 util.upload; import java.io.ioexception; import java.io.inputStream; import java.util.date; import java.util.properties; import java.util.miter; import java.util.timertask; import javax.servlet.servletcontext; javax.servlet.servletcontextListener;/ ** * 시간 청취자 * */ public class tempfilelistener 구현 servletcontextListener {개인 타이머 타이머; Private SystemTaskTest SystemTask; 개인 정적 문자열 Every_Time_run; static {properties proper = new Properties (); inputStream instrem = tempfileManager.class.getClassLoader () .getResourceasStream ( "tempfile.properties"); try {prop.load (instrem); System.out.println (악기); every_time_run = prop.getProperty ( "Every_Time_run"); } catch (ioexception e) {e.printstacktrace (); } 마침내 {try {instem.close (); } catch (ioexception e) {e.printstacktrace (); }}} // Listener 초기 방법 공개 void 컨텍스트 티어 화 (servletcontextevent scce) {timer = new Timer (); SystemTask = new SystemTaskTest (sce.getServletContext () .getRealPath ( "/"), sce.getServletContext ()); {system.out.println ( "타이머 시작")을 시도하십시오. // 리스너는 웹 사이트 문자열의 루트 디렉토리를 가져옵니다. longtime = long.parselong (Every_time_run) * 1000; // 루프 실행 시스템의 시간. // 첫 번째 매개 변수는 실행될 코드이며, 두 번째 매개 변수는 실행을 시작할 때이며 세 번째 매개 변수는 실행 중 얼마나 자주 실행되는지입니다. TIMER.SCEDULE (SystemTask, 10000, Time)의 실행을 반복합니다. System.out.println ( "작업 일정이 추가되었습니다"); } catch (예외 e) {e.printstacktrace (); }} public void contextDestroyed (servletcontexTevent scal) {try {timer.cancel (); } catch (예외 e) {}}} / *** Time Tasker* / class SystemTaskTest 확장 TimertASK {private servletContext 컨텍스트; 개인 문자열 경로; public SystemTaskTest (String Path, ServletContext Context) {this.path = path; this.context = 컨텍스트; } / *** run* / public void run () {tempfilemanager etf; {system.out.println ( "작업 시작!"); // 실행될 코드 System.out.println (새 날짜 (). tolocalestring ()); ETF = 새로운 tempfileManager (경로); etf.run (); System.out.println ( "작업 실행이 완료되었는지!"); } catch (예외 e) {e.printstacktrace (); }}}위의 내용은 청취자 일 뿐이며 정기적으로 임시 파일을 삭제하는 메소드를 호출해야합니다. 특정 구현은 다음 클래스입니다
패키지 util.upload; import java.io.file; import java.io.ioexception; import java.io.inputStream; import java.util.date; import java.util.properties;/*** 서버에서 파일을 구제합니다*/public classfilememanager {// pather strent emplements {// pathrent strent emplements = "14 파일 스토리지 시간은 하루 정적 {properties proper = new Properties ()입니다. inputStream instem = tempfileManager.class.getClassLoader () .getResourceAsStream ( "execl.Properties"); try {prop.load (instrem); rendention_time = prop.getProperty ( "file_retention_time"); } catch (ioexception e) {e.printstacktrace (); } 마침내 {try {instem.close (); } catch (ioexception e) {e.printstacktrace (); }}} /*** 생성자. 초기화 매개 변수 * @param path */ public tempfileManager (문자열 경로) {this.path = path; } / *** 스레드가 run ()에서 실행하려는 코드를 넣습니다.* / public void run () {system.out.println ( "파일 관리 start ==============================================================================="파일 (파일); deletefiles (파일) / ** * 배치 삭제 파일 * * @param 폴더 * / public void deletefiles (filder.isdirectory ()) {files = folder.listfiles (files.length <= 0); if (candeletefile (폴더)) {폴더 i = 0; i ++; if (candeletefile (file)) {if (file.delete ()) {system.out.println ( "file" + file.getname () + "성공적으로 삭제!")을 충족합니다. } else {system.out.println ( "file" + file.getName () + "삭제 실패!이 파일이 사용될 수 있습니다"); }} else {}} else {system.out.println ( "삭제할 파일 없음"); }} catch (예외 e) {System.out.println ( "파일 삭제 실패 ============"); e.printstacktrace (); }} / *** 파일을 삭제할 수 있는지 결정* / private boolean candeletefile (파일 파일) {date filedate = getFileDate (파일); 날짜 = 새 날짜 (); longtime = (date.gettime () - filedate.gettime ()) / 1000 / 60 -integer.parseint (resentent_time); // 현재 시간과 파일 간격 // system.out.println ( "time =="+time) 사이의 분; if (time> 0) {return true; } else {return false; }} / ** * 파일의 마지막 수정 시간을 가져옵니다 * * @param file * @return * / private date getFileDate (파일 파일) {long modifiedtime = file.lastModified (); 날짜 d = 새 날짜 (modifiedtime); 반환 d; }}파일이 시간이 초과되는지 여부를 결정하고 시간이 초과되면 폴더를 자동으로 삭제할 수 있습니다.
위의 내용은이 기사에 관한 모든 것입니다. 모든 사람들이 Java 프로그래밍을 배우는 것이 도움이되기를 바랍니다.