파일 업로드는 웹 응용 프로그램에서 매우 일반적입니다. 인터넷에서 Java에서 개발 된 많은 파일 업로드 구성 요소가 있기 때문에 JSP 환경에서 파일 업로드 기능을 구현하는 것은 매우 쉽습니다. 이 기사는 Commons-FileUpload 구성 요소를 예제로 가져와 JSP 응용 프로그램에 파일 업로드 기능을 추가합니다.
Common-FileUpload 구성 요소는 Apache의 오픈 소스 프로젝트 중 하나이며 http://jakarta.apache.org/commons/fileupload/에서 다운로드 할 수 있습니다.
이 구성 요소를 사용하면 한 번에 하나 이상의 파일을 업로드 할 수 있으며 파일 크기를 제한 할 수 있습니다.
다운로드 후 zip 패키지를 압축하고 Commons-FileUpload-1.0.jar를 WebAppWeb-Inflib 아래의 Tomcat의 WebApps로 복사하십시오. 디렉토리가 존재하지 않으면 자신의 디렉토리를 작성하십시오.
파일 업로드 용 새 서블릿 생성 : upload.java :
java.io.*; java.util.*; javax.servlet.*; javax.servlet.http.*import; import org.apache.commons.fileupload.*; 공개 클래스 업로드 확장 httpservlet {private string ubloadpath = "c : ubload"; // 파일 업로드를위한 디렉토리 개인 문자열 temppath = "c : uploadtmp"; // 임시 파일 디렉토리 public void dopost (httpservletrequest request, httpservletresponse 응답) ioexception, servletexception {}}dopost () 메소드에서 서블릿이 브라우저에서 발행 한 게시물 요청을 수신하면 파일 업로드를 실현합니다. 샘플 코드는 다음과 같습니다.
public void dopost (httpservletrequest 요청, httpservletreponse response)는 ioexception, servletexception {try {diskfileupload fu = new diskfileupload (); // 최대 파일 크기를 설정하십시오. 여기에 4MBFU.SETSIZEMAX (4194304)가 있습니다. // 버퍼 크기를 설정하십시오. 여기에 4KBFU.SETSIZETHRESHOLD (4096)가 있습니다. // 임시 디렉토리를 설정합니다 : fu.setRepositoryPath (temppath); // 모든 파일을 가져옵니다 : list fileItems = fu.parserequest (요청); iterator i = fileitems.iterator (); // 각 파일을 순서대로 처리합니다. // 파일 이름을 얻습니다. 파일 이름에는 경로가 포함됩니다. String filename = fi.getName (); // 여기에서 사용자 및 파일 정보를 녹음 할 수 있습니다 // ... // 파일에 쓰기, 잠정 파일 이름은 a.txt이며 파일 이름은 filename에서 추출 될 수 있습니다 : fi.write (새 파일 (uploadpath + "a.txt"); }} catch (예외 e) {// 오류 페이지로 점프 할 수 있습니다}}구성 파일에서 지정된 업로드 폴더를 읽으려면 init () 메소드에서 실행할 수 있습니다.
public void init ()는 servletexception {uploadpath = .... temppath = .... // 폴더가 존재하지 않으면 자동으로 생성됩니다 : if (! new file (uploadpath) .isdirectory ()) 새 파일 (uploadpath) .mkdirs (); if (! new file (temppath) .isdirectory ()) 새 파일 (temppath) .mkdirs (); }서블릿을 컴파일하고 클래스 경로를 지정하려면 Commons-Upload-1.0.jar 및 TomcatcommonLibservlet-api.jar를 포함하십시오.
서블릿을 구성하고 메모장을 사용하여 WebAppWeb-infweb.xml에 대한 tomcatwebapps를 열고 그렇지 않은 경우 새 것을 만듭니다.
일반적인 구성은 다음과 같습니다.
〈? xml 버전 = "1.0"encoding = "iso-8859-1"? − <! doctype web-appublic "-// Sun Microsystems, Inc.//dtd 웹 응용 프로그램 2.3 // en "" "http://java.sun.com/dtd/web-app_2_3.dtd"> <Web-App> <servlet> <servlet-name> 업로드 〈/servlet-name> <servlet-class> 업로드 </s ervlet-class> <servlet-mapping <servlet-name> 업로드 </servlet-name> <Url-pattern>/fileUpload 〈/url-pattern 〈/servlet-mapping </web-app <
서블릿을 구성한 후 Tomcat을 시작하고 간단한 HTML 테스트를 작성하십시오.
<양식 action = "fileUpload"method = "post"encType = "multipart/form-data"name = "form1"> 〈input type = "file"name = "file"> 〈입력 유형 = "submit"name = "value"value = "upload"> 〈/form>
참고 action = "fileUpload"여기서 fileUpload는 서블릿을 구성 할 때 지정된 URL 패턴입니다.
새우에 대한 코드는 다음과 같습니다.
이 업로드는 SmartUpload보다 사용하기가 훨씬 쉽습니다. 그것은 많은 버그가있는 SmartUpload와 달리, Bytes에 의해 하나씩 완전히 만들어졌습니다.
통화 방법 :
업로드 = 새 업로드 (); UP.INIT (요청); /**는 setSavedir (string savedir)를 호출 할 수 있습니다. 저장 경로를 설정하고 SetMaxFilesize (긴 크기)를 호출하여 업로드 된 파일의 최대 바이트를 설정하십시오. 업로드 후 파일 이름을 설정하려면 settagFileName (string)을 호출하여 (첫 번째 파일에만 유효 함)*/up. uploadfile ();
그런 다음 문자열 [] names = up.getFilename (); 업로드 된 파일 이름을 가져 오면 파일의 절대 경로는
저장된 디렉토리 savedir+"/"+names [i];
UP.GetParameter ( "Field")를 통해 업로드 된 텍스트 또는 UP.GetParametErvalues ( "Foded")를 얻을 수 있습니다.
다중 확인란과 같은 이름의 필드 값을 얻으십시오.
다른 사람들을 직접 시도하십시오.
소스 코드는 다음과 같습니다.
패키지 com.inmsg.beans; java.io.*; java.util.*; javax.servlet.*; javax.servlet.http.*import; 공개 클래스 업로드 {private String savedir = "."; // 파일을 저장하는 경로 개인 문자열 contentType = ""; // 문서 유형 개인 문자열 charset = ""; // 문자 세트 private arraylist tmpfilename = new ArrayList (); // 파일 이름을 저장하기위한 임시 데이터 구조 private hashtable 매개 변수 = new Hashtable (); // 매개 변수 이름과 값을 저장하는 데이터 구조 프라이버시 ServletContext 컨텍스트; // 개인 httpservletRequest 요청을 초기화하는 데 사용되는 프로그램 컨텍스트; // 요청 객체에서 전달하는 데 사용되는 인스턴스 개인 문자열 경계 = ""; // 메모리 데이터 분리기 개인 int Len = 0; // 바이트 길이는 실제로 개인 문자열 queryString 때마다 내부에서 읽습니다. 개인 int 수; // 업로드 된 파일의 총 수 개인 문자열 [] filename; // 업로드 된 파일 이름 배열 비공개 long maxFilesize = 1024 * 1024 * 10; // 최대 파일 업로드 바이트; 개인 문자열 tagfilename = ""; 공개 최종 void init (httpservletrequest 요청) servletexception {this.request = request; 경계 = request.getContentType (). substring (30); // 메모리 내 데이터를 가져옵니다 QueryString = request.getQueryString (); } public String getParameter (String S) {// 지정된 필드의 매개 변수 값을 가져 오는 데 사용됩니다. } return (string) parameter.get (s); } public String [] getParametErvalues (String s) {// 동일한 이름 필드로 지정된 매개 변수 배열을 가져 오는 데 사용됩니다. if (parameter.isempty ()) {return null; } 열거 e = parameter.keys (); while (e.hasmoreElements ()) {String key = (string) e.nextElement (); if (-1 !! }} if (al.size () == 0) {return null; } string [] value = new String [al.size ()]; for (int i = 0; i 〈value.length; i ++) {value [i] = (string) al.get (i); } 반환 값; } public String getQueryString () {return QueryString; } public int getCount () {return count; } public String [] getFileName () {return filename; } public void setMaxFilesize (긴 크기) {maxFilesize = size; } public void settagfilename (String filename) {tagfilename = filename; } public void setsavedir (String Savedir) {// 파일 업로드를 위해 저장할 경로를 설정 this.savedir = savedir; 파일 testDir = 새 파일 (savedir); // 디렉토리가 존재하는지 확인하려면 아니오가 있으면 디렉토리를 작성합니다. }} public void setcharset (String charset) {// 문자를 설정하십시오. charset = charset; } public boolean uploadfile ()는 servletexception, ioexception {// user setcharset (request.getCharacterEncoding ())에서 호출 된 UPLOAD 메소드를 던졌습니다. return uploadFile (request.getInputStream ()); } private boolean uploadFile (servletInputStream servletInputStream) 던지기 // 중앙 저장 데이터를 얻는 주요 방법 servleTeXception, ioException {String line = null; 바이트 [] 버퍼 = 새로운 바이트 [256]; while ((line = readline (buffer, servletinputstream, charset))! = null) {if (if ( "content-disposition : form-data;")) {int i = line.indexof ( "filename ="); if (i> = 0) {// delimiter의 설명에 filename = =있는 경우 파일 string fname = getFilename (line)의 인코딩 된 내용임을 의미합니다. if (fname.equals ( "")) {계속; } if (count == 0 && tagfilename.length ()! = 0) {String ext = fname.substring ((fname.lastIndexof ( ".") + 1)); fname = tagfilename + "." + 내선; } tmpfilename.add (fname); 카운트 ++; while ((line = readline (buffer, servletinputStream, charset))! = null) {if (line.length () <= 2) {break; }} 파일 f = 새 파일 (savedir, fname); fileoutputStream dos = 새 FileOutputStream (f); 긴 크기 = 0l; while ((line = readline (buffer, servletinputstream, null))! = null) {if (line.indexof (boundary)! = -1) {break; } size += len; if (size> maxFilesize) {trans new ioException ( "파일" + maxFilesize + "바이트!"); } dos.write (Buffer, 0, Len); } dos.close (); } else {// 그렇지 않으면 필드 인코딩 문자열 key = getkey (line)의 내용입니다. 문자열 값 = ""; while ((line = readline (buffer, servletinputStream, charset))! = null) {if (line.length () <= 2) {break; }} while ((line = readline (buffer, servletinputStream, charset))! = null) {if (line.indexof (boundary)! = -1) {break; } value += line; } put (key, value.trim (), 매개 변수); }}} if (QueryString! = null) {string [] eark = split (QueryString, "&"); for (int k = 0; k 〈eary 길이; k ++) {string [] nv = split (각 [k], "="); if (nv.length == 2) {put (nv [0], nv [1], 매개 변수); }}} filename = new String [tmpfilename.size ()]; for (int k = 0; k <filename.length; k ++) {filename [k] = (string) tmpfilename.get (k); // arrayList에 임시 파일 이름을 ehouse}} if (filename.length == 0) {return false; // filename 데이터가 비어 있으면 파일이 업로드되지 않았 음을 의미} true를 반환합니다. } private void put (문자열 키, 문자열 값, Hashtable HT) {if (! ht.containskey (key)) {ht.put (키, 값); } else {// 이미 같은 이름의 키가있는 경우 현재 키의 이름을 바꿔야합니다. 동시에 키 시도 {thread.currentthread (). sleep (1)과 동일한 이름을 형성하지 않도록주의하십시오. // 동일한 ms} catch에서 두 개의 동일한 키를 생성하지 않기 위해 (예외 e) {} key += "||||||||||||||" + System.CurrentTimeMillis (); ht.put (키, 값); }}/* Call ServletInputStream.Readline (byte [] b, int offset, length) 메소드는 ServletInputStream 스트림에서 지정된 바이트 배열에 이르기까지 줄을 읽습니다. 선을 수용 할 수 있도록 바이트 [] B는 256 이상이어야합니다. 다시 작성된 readline에서는 멤버 변수 LEN이 실제 바이트 읽기 수로 호출됩니다 (일부 선은 256 미만). 파일 컨텐츠를 작성할 때 LEN 길이의 바이트는 BYTE []의 전체 길이 대신 바이트 배열에서 작성해야합니다. 그러나 다시 작성된 메소드는 문자열을 반환하여 실제 컨텐츠를 분석하고 LEN을 반환 할 수 없으므로 LEN은 회원 변수로 설정되어 읽기 작업 할 때마다 실제 길이를 할당합니다. 즉, 파일의 컨텐츠를 처리 할 때는 시작 및 종료 표시를 분석하기 위해 문자열 형식으로 데이터를 반환하고 동시에 바이트 []의 형태로 파일 출력 스트림에 기록해야합니다. */private String readline (byte [] linebyte, servletInputStream servletInputStream, String charset) {try {len = servletInputStream.Readline (lineByte, 0, lineByte.length); if (len == -1) {return null; } if (charset == null) {return new String (LineByte, 0, Len); } else {return new String (LineByte, 0, Len, Charset); }} catch (예외 _ex) {return null; }} private String getFileName (String line) {// 파일 이름을 설명에서 분리 if (line == null) {return ""; } int i = line.indexof ( "filename ="); line = line.substring (i + 9) .trim (); i = line.lastIndexof ( ""); if (i <0 || i> = line.length () -1) {i = line.lastIndexof ( "/"); if (line.equals ( "" "") {return ""; } if (i <0 || i> = line.length () -1) {return line; }} return line.substring (i + 1, line.length () -1); } private String getKey (String line) {// 필드 이름을 설명에서 분리 if (line == null) {return ""; } int i = line.indexof ( "name ="); line = line.substring (i + 5) .trim (); return line.substring (1, line.length () -1); } public static string [] split (문자열 strob, String mark) {if (strob == null) {return null; } StringTokenizer st = new StringTokenizer (strob, mark); ArrayList tmp = new ArrayList (); while (st.hasmoretokens ()) {tmp.add (st.nextToken ()); } string [] strarr = new String [tmp.size ()]; for (int i = 0; i <tmp.size (); i ++) {strarr [i] = (string) tmp.get (i); } return strarr; }} 다운로드는 실제로 매우 간단합니다. 다음과 같이 처리하는 한 문제가 발생하지 않습니다. public void download (String filepath, httpservletresponse 응답, 부울 isonline) 예외 {file f = new File (FilePath); if (! f.exists ()) {response.senderror (404, "파일 찾기!"); 반품; } bufferedInputStream br = new bufferedInputStream (new FileInputStream (f)); 바이트 [] buf = 새로운 바이트 [1024]; int len = 0; response.reset (); // (isonline) {// OnOnoPen 메소드 URL U = new URL ( "file : //"+filepath); response.setContentType (u.openConnection (). getContentType ()); response.setHeader ( "Content-Disposition", "Inline; filename ="+f.getName ()); // 파일 이름은 UTF-8으로 인코딩되어야합니다} else {// 순수한 다운로드 메소드 응답 .setContentType ( "application/x-msdownload"); response.setheader ( "content-disposition", "첨부 파일; filename =" + f.getname ()); } outputStream out = response.getOutputStream (); while ((len = br.read (buf))> 0) out.write (buf, 0, len); br.close (); out.close (); }