파일 업로드는 무엇입니까?
파일 업로드는 사용자 정보를 저장하는 것입니다.
파일을 업로드 해야하는 이유는 무엇입니까?
사용자가 등록하면 사용자가 사진을 제출해야 할 수도 있습니다. 이 사진을 저장해야합니다.
업로드 구성 요소 (도구) 업로드 도구를 사용해야하는 이유는 무엇입니까?
구성 요소를 업로드 해야하는 이유는 무엇입니까? 클라이언트의 데이터를 얻으려면 일반적으로 GetParameter () 메소드를 통해 얻을 수 있습니다.
업로드 된 파일 데이터는 MIME 프로토콜로 나누고 양식은 이진에 캡슐화됩니다. 다시 말해 : getParameter ()는 업로드 된 파일의 데이터를 얻을 수 없습니다.
먼저 HTTP 파일 업로드가 데이터를 가져 오는 방법을 살펴 보겠습니다.
JSP 페이지, 양식은 ENCTEPE : Multipart/Form-Data를 지정해야합니다
<form action = "$ {pagecontext.request.contextpath}/servlet/uploadservlet1"encticpe = "multipart/form-data"method = "post"> upload user : <input type = "text"name = "username"> <br/> input type = "file" "file" "file 2 :> upload 2 :/> 이름 = "file2"> <br/> <입력 유형 = "제출"value = "제출"> </form>HTTP 패키지 잡기
서블릿에서 getParameter ()를 사용하여 데이터를 얻으십시오
문자열 ss = request.getParameter ( "username"); system.out.println (ss);
GetParameter를 직접 사용하여 데이터를 얻을 수 없습니다.
그래서 우리는 무엇을해야합니까? ? ? ? 요청 객체는 ServletInputStream 스트림을 제공하여 데이터를 읽습니다.
우리는 파일을 읽으려고 노력합니다
servletInputStream inputStream = request.getInputStream (); 바이트 [] 바이트 = 새로운 바이트 [1024]; int len = 0; while ((len = inputstream.read (bytes))> 0) {System.out.println (새 문자열 (Bytes, 0, Len)); }JSP 페이지에 추가 입력 제어를 추가하십시오
<입력 유형 = "텍스트"이름 = "비밀번호">
업로드 한 텍스트 파일은 111111이며 읽기 효과는 다음과 같습니다.
이제 파일 업로드 데이터를 읽을 수 있지만 이제 질문은 다음과 같습니다. 서버로 전송 된 데이터에서 파일의 업로드 된 데이터를 분리하는 방법은 무엇입니까? ? ? 우리는 위의 그림에서 본 적이 있습니다. 그들은 함께 혼합되어 있습니다.
일반적인 관행에 따라 분리하기가 어렵 기 때문에 구성 요소를 업로드해야합니다.
두 가지 유형의 FileUploads 업로드 구성 요소가 있습니다 [더 많은 작동] samrtupload [더 많은 작동] FileUpload
FileUpload 구성 요소를 사용하려면 2 개의 JAR 패키지를 가져와야합니다.
Commons-IO Commons-FileUpload 개발 단계 Parser Factory Object [DiskFileItemFactory] Parser Factory [ServletFileUpload]를 통해 구문 분석기를 작성하여 구문 분석 방법을 구문 분석하여 요청 객체를 구문 분석하고, 업로드 된 모든 내용 [목록] 목록을 가져옵니다. 각 객체가 업로드 된 파일인지 확인합니다. 정상적인 양식 필드 인 경우 필드 이름과 필드 값을 얻으십시오. 업로드 된 파일 인 경우 InputSteam 메소드를 호출하여 입력 스트림을 얻고 업로드 된 데이터를 빠르게 읽으십시오.
{// 1. Parser Factory DiskFileItemFactory Factory = New DiskFileItemFactory (); // 2. Parser ServletfileUpload 업로드 = New ServletfileUpload (Factory)를 받으십시오. // 3. if (! upload.ismultipartContent (request)) {// 양식 업로드는 일반적인 양식입니다. 그런 다음 기존의 반환 방법으로 데이터를 얻습니다. } // 양식을 업로드하려면 파서에 전화하여 업로드 된 데이터 목록을 구문 분석하려면 <fileItem> list = upload.parserequest (요청); // fileItem // 목록을 수송하고 첫 번째 업로드 입력 항목 데이터 파일 시민 개체 (파일 항목 : list) {if (item.isformfield ()) {// 얻은 것은 일반 입력 문자열 이름 = item.getFieldName (); // 입력 항목의 이름을 가져옵니다. 문자열 값 value = item.getString (); System.out.println (name + "=" + value); } else {// 업로드 입력 항목을 가져옵니다. string filename = item.getName (); // 업로드 파일 이름 C :/Documents and Settings/ThinkPad/Desktop/1.txt filename = filename.substring (filename.lastIndexof ( "//")+1); inputStream in = item.getInputStream (); // 데이터 업로드 데이터 int len = 0; 바이트 버퍼 [] = 새로운 바이트 [1024]; String savepath = this.getServletContext (). getRealPath ( "/Upload"); fileoutputStream out = 새 FileOutputStream (SavePath + "//" + filename); // 업로드 디렉토리에 파일을 쓰기 while } in.close (); out.close (); }}} catch (예외 e) {e.printstacktrace (); }일반 필드와 업로드 된 파일을 모두 읽고 얻을 수 있는지 테스트합니다!
SmartUpload
SmartUpload 구성 요소를 사용하려면 smartupload.jar 개발 패키지를 가져와야합니다.
빠른 시작
// 인스턴스화 구성 요소 SmartUpload SmartUpload = new SmartUpload (); // 업로드 작업 초기화 작업 smartUpload.initialize (this.getServletConfig (), 요청, 응답); {// 준비 준비 SmartUpload.upload (); // 일반 데이터의 경우 요청 객체가 제출 된 매개 변수를 얻을 수 없을 정도로 간단합니다. 또한 smartUpload String password = smartUpload.getRequest (). getParameter ( "password")에 의존해야합니다. System.out.println (비밀번호); // 업로드 폴더 폴더 smartUpload.save ( "uploadfile"); } catch (smartUploadexception e) {e.printstacktrace (); }시험
마찬가지로 파일을 업로드 파일 폴더에 업로드 할 수 있습니다. 코드의 양은 실제로 많이 줄어 듭니다!
일반 필드의 매개 변수를 얻을 수도 있습니다
파일 이름을 중국의 garbled 코드로 변경하고 데이터를 업로드하기 위해 중국어가 달린 코드를 변경했는데 코드가 뒤덮였습니다.
양식에 의해 제출 된 중국 데이터도 차별화되어 있습니다.
위에서 언급했듯이 파일 데이터 업로드 형식은 이진에 캡슐화되므로 요청을 사용하여 데이터를 인코딩하면 양식에서 제출 한 데이터에 대해 작동하지 않습니다!
FileUpload는 garbled 코드를 해결합니다
FileUpload를 사용하여 차량 문제를 해결하는 것은 매우 간단합니다
Brebled Chinese 파일 이름을 해결하십시오. 파서를 얻은 후 파서의 인코딩을 UTF-8로 설정하십시오!
// 업로드 파일 인코딩을 설정하여 setheaderEncoding ( "UTF-8");
garbled 양식 데이터를 해결하십시오. 양식 값을 얻을 때는 UTF-8 인코딩을 사용하여 얻을 수 있습니다.
문자열 값 = fileItem.getString ( "UTF-8");
효과:
SmartUpload는 차량 코드를 해결합니다
이 구성 요소는 차량 코드 문제를 해결하기 위해 약간 번거 롭습니다. 온라인에서 다양한 솔루션을 찾았지만 간단한 솔루션을 찾을 수 없었습니다 ...
따라서 데이터에 중국어가 포함되지 않으면 SmartUpload 구성 요소를 사용하고 중국 데이터가 포함 된 경우 FileUpload 구성 요소를 사용하십시오!
여러 파일을 업로드하고 동적으로 업로드 컨트롤을 추가하십시오
지금 업로드 할 여러 파일이 있다고 가정하고 업로드 할 파일 수가 확실하지 않다고 가정합니다. 그래서 우리는 무엇을해야합니까? ? ?
페이지에 파일을 업로드하기위한 많은 컨트롤을 나열하는 것은 불가능합니다. 사용자가 많은 컨트롤을 사용할 수 없다면 폐기물입니다.
따라서 파일 업로드를위한 컨트롤을 동적으로 추가하려고합니다. 사용자가 파일을 업로드하려면 컨트롤을 동적으로 생성하면됩니다!
분석
페이지에서 컨트롤을 동적으로 생성하려면 JavaScript 코드를 사용하는 것 이상입니다.
그래서 우리는 무엇을합니까? ?
이렇게하겠습니다. 사용자가 파일을 업로드하려면 버튼을 클릭하면 버튼이 이벤트를 바인딩하여 파일 업로드 컨트롤을 생성합니다.
더 완벽하게 수행하려면 파일 업로드 컨트롤이 생성 될 때마다 삭제 버튼도 제공되어 컨트롤을 삭제합니다!
컨트롤을로드하고 생성하려는 컨트롤을로드하려면 DIV를 사용해야합니다. 사용자가 삭제하기 위해 클릭하면 삭제 버튼을 숨기고 컨트롤을 파일 업로드해야합니다. 따라서 중첩 된 divs를 사용하는 것이 가장 좋습니다!
코드 페이지 코드 :
<table> <tr> <td> 사용자 업로드 사용자 : </td> <td> <input type = "text"name = "username"> </td> </td> <td> 파일 추가 파일 추가 </td> <td> <input type = "value ="value = "value"</td> <td> <td> <td> </td> </tr> </table>
자바 스크립트 코드
<script type = "text/javaScript"> 함수 addUploadFile () {// 파일 업로드 생성 제어 var input = document.createElement ( "input"); input.type = '파일'; input.name = 'filename'; // 삭제 버튼 생성 var del = document.createElement ( "입력"); del.type = '버튼'; del.Value = '삭제'; // 내부 div var var innerdiv = document.createElement ( "div") 생성; // 두 컨트롤을 InnerDiv에 바인딩합니다. AppendChild (입력); Innerdiv. AppendChild (del); // 외부 div 컨트롤을 가져 와서 내부 div를 외부 div var outterdiv = document.getElementById ( "file")에 바인딩합니다. outterdiv. AppendChild (InnerDiv); // 이벤트 del.onClick = function delete () {// 내부 div를 죽이려면 외부 div의 제거 메소드를 호출 this.parentNode.parentNode.RemoveCheand (this.parentNode); }} </script>파일 업로드 세부 사항 업로드 된 파일의 크기가 설정된 파일의 크기보다 큰 경우 파일은 임시 파일을 사용하여 업로드 할 때 업로드 된 데이터를 저장합니다. 업로드 후 임시 파일을 삭제해야합니다. 웹 서버에서 업로드 파일을 관리 할 수없는 위치, 그렇지 않으면 보안 문제가 발생할 수 있습니다 [다른 사람이 평균을 통해 업로드 파일을 수정할 수 있습니다.] 업로드 파일 이름이 동일하면 원래 업로드 파일이 덮어 쓸 수 있습니다. 고유 한 파일 이름을 생성하고 싶습니다. 사용자 수가 크면 많은 파일이 업로드되어 있습니다. 그런 다음 모든 업로드 파일을 하나의 디렉토리에 저장해서는 안됩니다. 이는 디스크가 중단 될 수 있습니다. 따라서 업로드 된 파일을 다른 디렉토리로 분산시켜야합니다. 분석
임시 파일을 삭제하는 문제는 매우 간단합니다. 모든 작업이 완료된 후 Delete () 메소드의 파일 메소드 만 호출하면됩니다.
웹 서버에서 업로드 된 파일이 관리되는 것을 방지하기 위해 업로드 된 파일 위치를 웹 -INF/ 디렉토리에 배치 할 수 있습니다!
동일한 파일 이름의 경우 사용자가 업로드 된 파일 이름으로 업로드 한 UUID+ 파일 이름을 사용할 수 있습니다. 이러한 파일 이름은 고유합니다.
업로드 된 파일을 분해하려면 해시 코드 알고리즘을 사용하여 분해해야합니다.
낮은 4 비트는 제 1 레벨 디렉토리 생성 5-8 비트 생성 2 단계 디렉토리 코드를 생성합니다.
비교적 완전한 업로드 파일 코드를 작성해 봅시다
해시 코드 알고리즘을 사용하여 저장된 디렉토리를 분해하십시오
개인 문자열 makedirpath (String filename, String Path) {// 파일 이름 int hashcode = filename.hashcode ()를 통해 기본 및 보조 디렉토리를 계산합니다. int dir1 = 해시 코드 & 0xf; int dir2 = (해시 코드 & 0xf0) >> 4; 문자열 dir = path + "//" + dir1 + "//" + dir2; // 디렉토리가 존재하지 않으면 디렉토리 파일 파일 = 새 파일 (dir)을 만듭니다. if (! file.exists ()) {file.mkdirs (); } // 전체 경로를 반환합니다. }고유 한 파일 이름을 생성합니다
개인 문자열 makefilename (String filename) {// 밑줄을 사용하여 UUID와 파일 이름을 구분하면 나중에 파일 이름을 구문 분석 할 수 있습니다. return uuid.randomuuid (). tostring () + "_" + filename; }업로드 된 코드
// 공장 생성 공장 DiskFileItemFactory Factory = New DiskFileItemFactory (); // 공장 ServletFileUpload FileUpload = New ServletFileUpload (Factory)를 통해 구문 분석기 생성; // 업로드 Code FileUpload.SetheAderEncoding ( "UTF-8")을 설정합니다. // if (! fileUpload.ismultipartContent (request)) {// 양식을 일반 양식으로 업로드 한 다음 기존의 반환 방법으로 데이터를 얻습니다. } try {// 요청 객체를 구문 분석하여 목록을 가져옵니다 [업로드 된 모든 내용을로드] 목록 <fileItem> list = fileUpload.parsEerquest (요청); //로드 된 컨텐츠가 일반 필드인지 (fileItem fileItem : list)의 업로드 파일인지 결정하기 위해 목록을 통과합니다. {// 일반 입력 항목 인 경우 (fileItem.isformfield ()) {// 입력 항목의 이름과 값을 가져옵니다. 문자열 값 = fileItem.getString ( "UTF-8"); System.out.println (name + "=" + value); } else {// 업로드 파일 인 경우 // 업로드 이름을 가져옵니다 [경로 이름 포함] 문자열 filename = fileItem.getName (); // 파일 이름을 가로 채기 filename = filename.substring (filename.lastIndexof ( "//") + 1); // 고유 한 파일 이름을 생성합니다. filename = makeFileName (filename); inputStream inputStream = fileItem.getInputStream (); // 프로젝트 경로를 가져 와서 업로드 된 파일을 프로젝트 문자열 경로 = this.getServletContext (). getRealPath ( "/web-inf/uploadfile")에 기록합니다. // 산란 된 디렉토리 경로를 가져옵니다. String realPath = Makedirpath (filename, path); fileoutputStream outputStream = 새 FileOutputStream (realPath + "//" + filename); 바이트 [] 바이트 = 새로운 바이트 [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {outputStream.write (bytes, 0, len); } inputStream.close (); outputStream.close (); // 임시 파일의 데이터 삭제 fileitem.delete (); }}} catch (fileUploadexception e) {e.printstacktrace (); }효과 : 디렉토리가 성공적으로 분해되었고 파일 이름은 고유했습니다.
업로드 된 디렉토리에 파일을 나열하고 다운로드를 제공합니다.
respose 객체를 설명 할 때 파일 다운로드가 설명되었습니다. 이번에는 파일 다운로드를 통합하기 위해 작은 사례를 작성합니다.
업로드 디렉토리에는 3 개의 파일이 있습니다
분석
먼저 디렉토리에 모든 파일을 나열하십시오. 나중에 파일 이름에 따라 파일을 다운로드해야하므로 맵 컬렉션을 사용하여 모든 파일을 저장합니다.
다운로드 부분도 매우 간단합니다. 파일 이름에 따라 해당 파일을 찾고 파일 위치를 업로드하고 읽고 쓰고 메시지 헤더를 수정하여 다운로드를 달성하십시오.
파일로드 및 업로드 경로를 가져 와서 재귀 적으로 파일을 찾아 모든 파일을 찾아서 (파일인지 또는 재귀 종료 여부를 판단) 맵 수집에로드 한 다음 맵 컬렉션을 프론트 데스크에 전달하여 사용자가 다운로드 할 때 표시 할 때 맵 컬렉션을 전달한 다음 원래 이름에 따라 절대 경로를 얻습니다. 리소스가 존재하면 사용자는 코드를 다운로드하고 맵 컬렉션에 Web-Inf/ Directory에 저장된 모든 파일을 넣을 수 있습니다.
보호 된 void dopost (httpservletrequest 요청, httpservletreponse response)는 servletexception, ioexception {// 업로드 된 파일이 문자열 filepath = this.getServletContext (). getRealPath ( "/web-inf/uploadfile"); 지도 맵 = new Hashmap (); // 재귀를 사용하여 모든 파일을 가져 와서지도 컬렉션에 추가하십시오 getAllFiles (새 파일 (filepath), 맵); request.setAttribute ( "지도",지도); request.getRequestDispatcher ( "/listfile.jsp"). FORMPER (요청, 응답); } private void getAllFiles (File FilePath, Map Map) {// 파일이 아닌 경우 폴더 인 경우 (! FilePath.isfile ()) {// 폴더에 모든 파일을 나열 (파일, 폴더 일 수 있음) 파일 [] fillepath.listfiles (); for (파일 파일 : 파일) {// 획득 된 파일 (또는 폴더) 및 getAllFiles (파일, 맵)를 판단합니다. }} else {// else 문을 입력해야합니다. 파일이어야합니다. // 파일 이름을 가져옵니다. string filename = filepath.getname (). substring (filepath.getname (). lastIndexof ( "_") + 1); // 파일의 전체 이름을 키로, 파일 이름을 맵 수집 맵에서 값으로 저장합니다. }}JSP 페이지에 다운로드 가능한 파일을 표시하십시오
<c : foreach items = "$ {map}"var = "me"> <c : url var = "url"value = "/downfileservlet"> <c : param name = "filename"value = "$ {me.key}"> </c : param> </c : url> $ {me.value} <a href = "rel}"replice} "rel}" </a> <br> </c : foreach>다운로드 된 서블릿을 구현하십시오
보호 된 void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioException {// 파일의 전체 이름을 가져옵니다. filename = requestParameter ( "filename"); // 중국 데이터 인 경우 트랜스 코딩이 필요합니다. filename = new String (filename.getBytes ( "iso8859-1"), "UTF-8"); // 파일이 저장된 위치를 가져옵니다. String path = this.getServletContext (). getRealPath ( "/web-inf/uploadfile"); // 파일은 해시 코드 별 파일 이름을 통해 저장되며 파일은 파일 이름 문자열 filerealpath = makeFilePath (filename, path)를 통해 얻습니다. System.out.println (filerealpath); // 파일이 존재하는지 파일 = 새 파일 (filerealpath)에 있는지 판단합니다. if (! file.exists ()) {request.setAttribute ( "message", "다운로드하려는 리소스는 존재하지 않습니다!"); request.getRequestDispatcher ( "/message.jsp"). FORMPER (요청, 응답); 반품 ; } // 존재 // 파일을 읽고 브라우저에 데이터를 작성하여 fileInputStream inputStream = new FileInputStream (FilerEalPath); 바이트 [] 바이트 = 새로운 바이트 [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {response.getOutputStream (). 쓰기 (bytes, 0, len); } inputStream.close (); // 브라우저에 다운로드 된 파일 문자열 이름 = filename.substring (filename.lastIndexof ( "_") + 1); response.setHeader ( "Content-Disposition", "첨부 파일; filename =" + urlencoder.encode (이름, "UTF-8")); } private String makeFilePath (String filename, String Path) {int hashcode = filename.hashcode (); int dir1 = 해시 코드 & 0xf; int dir2 = (해시 코드 & 0xf0) >> 4; 문자열 dir = path + "//" + dir1 + "//" + dir2 + "//" + filename; 반환 dir; }효과
기사에 오류가 있으면 저를 수정하면 모두가 서로 의사 소통 할 것입니다. Wulin.com을 지원 해주셔서 감사합니다.