First, the principle of file upload
1, the premise of file upload:
A, form form the method must be a post
B, Form form enctype must be multipart/form-data (determine the Post request method, the request body data type)
Note: When the enctype of the form is multipart/form-data, the traditional method of getting the request parameters is invalidated.
Request Body: (The MIME protocol is described, the body is multi-part)
-----------------------------7dd32c39803b2
Content-disposition:form-data; Name= "username"
Wzhting
-----------------------------7dd32c39803b2
Content-disposition:form-data; Name= "F1"; Filename= "C:\Documents and settings\wzhting\ Jean 岄 Bulb \a.txt"
Content-type:text/plain
Aaaaaaaaaaaaaaaaaa
-----------------------------7dd32c39803b2
Content-disposition:form-data; Name= "F2"; Filename= "C:\Documents and settings\wzhting\ Jean 岄 Bulb \b.txt"
Content-type:text/plain
bbbbbbbbbbbbbbbbbbb
-----------------------------7dd32c39803b2--
C, the type that provides input in the form is a file upload domain of type files
Second, the use of third-party components to achieve file upload
1. Commons-fileupload Components:
Jar:commons-fileupload.jar Commons-io.jar
2. Core class or interface
Diskfileitemfactory: Setting up the environment
public void Setsizethreshold (Int?sizethreshold): Sets the buffer size. The default is 10Kb.
When the uploaded file exceeds the buffer size, the FileUpload component will use the temporary file cache to upload the file
public void Setrepository (Java.io.File repository): Sets the storage directory for temporary files. The default is the system's temporary file storage directory.
Servletfileupload: Core upload Class (main function: Parse the body content of the request)
Boolean ismultipartcontent (Httpservletrequest?request): Determines whether the enctype of a user's form is of type Multipart/form-data.
List parserequest (HttpServletRequest request): Parse the contents of the requested body
Setfilesizemax (4*1024*1024);//Set the size of a single upload file
Upload.setsizemax (6*1024*1024);//Set Total file size
Fileitem: Represents an input field in a form.
Boolean Isformfield (): Whether it is a normal field
String getfieldname: Gets the field name of the normal field
String getString (): Gets the value of the normal field
InputStream getInputStream (): Gets the input stream of the upload field
String getName (): Gets the uploaded file name
Iii. 9 Questions to note in uploading documents
1, how to ensure the security of the server
Place the directory where you saved the uploaded files in the Web-inf directory.
2, Chinese garbled problem
2.1 Chinese request parameters for normal fields
String value = fileitem.getstring ("UTF-8");
2.2 The file name was uploaded in Chinese
Workaround: Request.setcharacterencoding ("UTF-8");
3. Problems with duplicate files being overwritten
System.currentmillions () + "_" +a.txt (Optimistic)
Uuid+ "_" +a.txt: Guaranteed file name unique
4, sub-directory storage uploaded files
Mode one: The current date to create a folder, the currently uploaded files are placed in this folder.
Method Two: Use the file name of the hash code to break the directory to store.
int hashcode = Filename.hashcode ();
1001 1010 1101 0010 1101 1100 1101 1010
hashcode&0xf; 0000 0000 0000 0000 0000 0000 0000 1111 &
---------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1010 Take hashcode 4 bit
0000~1111: Integer 0~15 total of 16
1001 1010 1101 0010 1101 1100 1101 1010
(hashcode&0xf0) 0000 0000 0000 0000 0000 0000 1111 0000 &
--------------------------------------------
0000 0000 0000 0000 0000 0000 1101 0000 >>4
--------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1101
0000~1111: Integer 0~15 total of 16
5. Restrict the types of files uploaded by users
It is not advisable to limit the file extension by judging it.
It is only by judging its MIME type. Fileitem.getcontenttype ();
6, how to limit the size of users to upload files
6.1 Single File size limit. Out of size friendly tips
Catch exception to prompt: Org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException
6.2 Total File size limit. Out of size friendly tips
Catch exception to prompt: Org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException
7. Issues with temporary files
The Commons-fileupload component does not delete temporary files that exceed the cache.
The Fileitem.delete () method deletes the temporary file. But be sure to close the stream.
8, multiple files upload, there is no issue of uploading content
if (filename==null| | "". Equals (Filename.trim ())) {
Continue
}
9. Upload Progress Detection
Register a Progress listener for servletfileupload, and pass the upload progress to the page to display
Pbytesread: Current number of bytes to read
Pcontentlength: Length of File
Pitems: The first few
public void update (long pbytesread, long pcontentlength,
int Pitems) {
System.out.println ("read:" +pbytesread+ ", File Size:" +pcontentlength+ ", Number of items:" +pitems ");
}
Four: File Upload example:
JSP Code:
<form action= "${pagecontext.request.contextpath}/servlet/uploadservlet" method= "post" enctype= "multipart/ Form-data "> user name: <input type=" text "name=" username "/><br/> file 1:<input type=" file "Name=" F1 "/><br/> files 2:<input type=" file "name=" F2 "/><br/> <input type=" Submit "value=" Save " /> </form>
Servlet Backend Code:
public class Uploadservlet extends HttpServlet {public void doget (HttpServletRequest request, HttpServletResponse Response) throws Servletexception, IOException {request.setcharacterencoding ("UTF-8"); Response.setcontenttype (" Text/html;charset=utf-8 "); PrintWriter pout = Response.getwriter (); try {//Get the real path to the uploaded file, string storepath = Getservletcontext (). Getrealpath ("/ Web-inf/files ");//Set environment Diskfileitemfactory factory = new Diskfileitemfactory (); Factory.setrepository (New File ( Getservletcontext (). Getrealpath ("/temp"));//Set temporary directory//Determine if the form is a Boolean of type Enctype=multipart/form-data Ismultipart = servletfileupload.ismultipartcontent (Request), if (!ismultipart) {System.out.println ("Big Silly Bird"), return; Servletfileupload Core class Servletfileupload upload = new Servletfileupload (factory);//upload.setprogresslistener (new Progresslistener () {////pbytesread: Current number of bytes read////pcontentlength: Length of File////pitems: The first few//public void update (long Pbytesread, Long Pcontentlength,//int pitems) {//system.out.println ("read:" +pbytesread+ ", File size:" +pcontentlength+ ", Number of items:" +pitems ";//}////}); Upload.setfilesizemax (4 * 1024 * 1024);// Set the size of a single upload file Upload.setsizemax (6 * 1024 * 1024);//Set Total file size//parsing list<fileitem> items = upload.parserequest (request); for (Fileitem item:items) {if (Item.isformfield ()) {//normal field string fieldName = Item.getfieldname (); String fieldvalue = item.getstring ("UTF-8"); System.out.println (fieldName + "=" + Fieldvalue);} else {//get MIME type string mimeType = Item.getcontenttype ();//Only allow upload of picture if (Mimetype.startswith ("image")) {// Upload field InputStream in = Item.getinputstream ();//upload filename string filename = Item.getname ();//C:\Documents Andif (filename== null| | "". Equals (Filename.trim ())) {continue;} settings\wzhting\ Jean 岄 Bulb \a.txt//a.txtfilename = filename.substring (filename.lastindexof ("\ \") + 1);//A.txtfileName = Uuid.randomuuid () + "_" + fileName; System.out.println (REQUEST.GETREMOTEADDR () + "==============" +filename);//build output stream//Scatter storage directory string Newstorepath = Makestorepath (Storepath, fileName);////web-inf/files and file name, create aNew storage Path///web-inf/files/1/12string StoreFile = newstorepath + "\ \" + filename;//web-inf/files/1/2/ Sldfdslf.txtoutputstream out = new FileOutputStream (storefile); byte b[] = new Byte[1024];int len = -1;while (len = In.rea D (b))! =-1) {out.write (b, 0, Len);} Out.close (); In.close (); Item.delete ();//delete temporary File}}}} catch ( Org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException e) {//A single file exceeds the size of the exception Pout.write (" Individual file size cannot exceed 4M ");} catch (Org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e) {//exception pout.write when the total file is out of size (" The total file size cannot exceed 6M ");} catch (Exception e) {e.printstacktrace ();}} Creates a new storage path based on/web-inf/files and file name/web-inf/files/1/12private string Makestorepath (String Storepath, String fileName) {int hashcode = Filename.hashcode (); int dir1 = hashcode & 0xf;//0000~1111: integer 0~15 total 16 int dir2 = (Hashcode & 0xf0) >> 4;//0000~1111: integer 0~15 A total of 16 string path = Storepath + "\ \" + dir1 + "\ \" + Dir2; Web-inf/files/1/12file file = new file (path); if (!file.exists ()) File.mkdirs (); return path;} public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException { Doget (request, Response);}}
--------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------- ---------
Five: File download
1. Display all photo information stored in the above:
Display all uploaded files, encapsulate them in the domain object, and give the JSP to display the public class Showallfilesservlet extends HttpServlet {public void doget ( HttpServletRequest request, HttpServletResponse response) throws Servletexception, IOException {map<string, String > map = new hashmap<string, string> ();//key:uuid filename; value: The old file name//Gets the root directory of the stored file String Storepath = Getservletcontext (). Getrealpath ("/web-inf/files");//recursively traverse one of the files in file = new file (Storepath); Treewalk (file,map);// To the JSP to show: How to encapsulate the data. In a map package. Key:uuid file name; value: Old filename request.setattribute ("map", map), Request.getrequestdispatcher ("/listfiles.jsp"). Forward ( request, response);} Traverse/web-inf/files All files, place the file name in Map private void Treewalk (file file, map<string, string> Map) {if (File.isfile ()) {/ /is a file string uuidname = File.getname ();//uuid_a_a.txt//Real file name string oldname = Uuidname.substring (Uuidname.indexof ("_") + 1); Map.put (Uuidname, oldname);} else{//is a directory file[] fs = File.listfiles (); for (file F:fs) {treewalk (F,MAP);}}} public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {doget (request, Response);}}
2. Display the contents of all Files listfiles.jsp page:
<body>
3. File Download Downloadservlet:public class Downloadservlet extends HttpServlet {public void doget (HttpServletRequest request, HttpServletResponse Response) throws Servletexception, IOException {response.setcontenttype ("Text/html;charset=utf-8"); OutputStream out = Response.getoutputstream (); String filename = request.getparameter ("filename"),//get request Way filename = new String (filename.getbytes ("iso-8859-1"), " UTF-8 ")//Chinese code//Intercept old file name string oldfilename = Filename.split (" _ ") [1];//Get the storage path string storepath = Getservletcontext (). Getrealpath ("/web-inf/files");//Get the full path of the file string FilePath = Makestorepath (storepath, filename) + "\ \" +filename;// Determines whether a file exists as a filename (FilePath), if (!file.exists ()) {Out.write ("Comparison! The file you want to download may no longer exist ". GetBytes (" UTF-8 ")); return;} InputStream in = new FileInputStream (file);//Notifies the client to open Response.setheader ("content-disposition", "attachment") as downloaded: Filename= "+urlencoder.encode (Oldfilename," UTF-8 ")); byte[] B = new Byte[1024];int len = -1;while ((len=in.read (b))!=-1) {Out.write (b, 0, Len);} In.close (); Out.write ("Download succeeded". GetbYtes ("UTF-8"));} public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException { Doget (request, response);} private string Makestorepath (String Storepath, String fileName) {int hashcode = Filename.hashcode (); int dir1 = Hashcode &A mp 0xf;//0000~1111: integer 0~15 total 16 int dir2 = (hashcode & 0xf0) >> 4;//0000~1111: integer 0~15 A total of 16 string path = Storepath + "\ \ "+ dir1 +" \ \ "+ Dir2; Web-inf/files/1/12file file = new file (path), if (!file.exists ()) file.mkdirs (); return path;}}