In the development of Web application system, the file upload and download function is a very common function, today it is the implementation of file upload and download function in Javaweb.
For file upload, the browser in the process of uploading the file as a stream to the server side, if directly using the servlet to get the input stream of the uploaded file and then parse the request parameters inside is more trouble, So the general choice is to use the Apache Open Source Tool common-fileupload This file upload component. This common-fileupload upload component jar package can go to Apache official web surface download, can also be found under the Lib folder of struts, struts upload function is based on this implementation. Common-fileupload is dependent on Common-io this package, so you need to download this package, you can also go directly to the MAVEN library to search for this package. If you use servlet3.0, you do not need to download the package, directly support the file upload.
Apache website also has a servlet part of the code demonstration and explanation, address: http://commons.apache.org/proper/commons-fileupload/
Environment directory:
Upload Code
<%@ page language= "java" pageencoding= "UTF-8"%><! DOCTYPE html> ${pagecontext.request.contextpath} Ensure that the path is correct after deployment <!--file upload must be set enctype= "Multipart/form-data" to the form <form action= "${pagecontext.request.contextpath}/uploadservlet" method= "post" enctype= "Multip Art/form-data "> Upload files: <input type=" file "name=" file "> <br> <input type= "Submit" value= "Upload" > </form> </fieldset> Develop a servlet that handles file uploads 1. Use annotations @multipartconfig to identify a servlet as a support file upload.
2, Servlet3.0 the Multipart/form-data POST request into part, through the part of the uploaded files to operate .
Package Servlet;import Java.io.file;import Java.io.fileoutputstream;import java.io.ioexception;import Java.io.inputstream;import Java.util.list;import Javax.servlet.servletexception;import Javax.servlet.annotation.multipartconfig;import Javax.servlet.annotation.webservlet;import Javax.servlet.http.httpservlet;import Javax.servlet.http.httpservletrequest;import Javax.servlet.http.httpservletresponse;import Org.apache.commons.fileupload.fileitem;import Org.apache.commons.fileupload.disk.diskfileitemfactory;import org.apache.commons.fileupload.servlet.servletfileupload;//use @webservlet to configure Uploadservlet access path @webservlet (name= " Uploadservlet ", urlpatterns="/uploadservlet ")//Use annotations @multipartconfig to identify a servlet as a support file upload @multipartconfig// Identity servlet Support File upload public class Uploadservlet extends HttpServlet {/** * */private static final long Serialversionuid = 1 l;public void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception, ioexcept Ion {//Get uploadedFile storage directory, the uploaded files are stored in the Web-inf directory, do not allow direct access to the outside world, to ensure the security of uploading files String Savepath = This.getservletcontext (). Getrealpath ("/we B-inf/upload "); File File = new file (Savepath); Determine if the saved directory for the uploaded file exists if (!file.exists () &&!file.isdirectory ()) {System.out.printl N (savepath+ "directory does not exist, need to create"); Create directory File.mkdir (); }//message prompt String message = ""; try{//Use Apache File Upload component to process file upload steps://1, create a diskfileitemfactory factory Disk Fileitemfactory factory = new Diskfileitemfactory (); 2. Create a file upload parser servletfileupload upload = new Servletfileupload (factory); Solve the upload file name of the Chinese garbled upload.setheaderencoding ("UTF-8"); 3, determine whether the data submitted is the upload form data if (! Servletfileupload.ismultipartcontent (Request)) { Get the data return in the traditional way; }//4, using the Servletfileupload parser to parse the uploaded data, the result of the parse is a list<fileitem> collection, each fileitem corresponding to the input of a form form list<fileitem> list = upload.parserequest (request); for (Fileitem item:list) {//If the data that is encapsulated in the fileitem is a normal input item if (Item.isformfield ()) { String name = Item.getfieldname (); Solve the problem of normal input data in Chinese garbled String value = item.getstring ("UTF-8"); Value = new String (value.getbytes ("iso8859-1"), "UTF-8"); SYSTEM.OUT.PRINTLN (name + "=" + value); }else{//if the upload file//Get uploaded file name is encapsulated in Fileitem, String filename = item.getn Ame (); SYSTEM.OUT.PRINTLN (filename); if (Filename==null | | filenamE.trim (). Equals ("")) {continue; }//Note: Different browser submissions are not the same file name, some browsers submitted by the file name is with a path, such as: C:\a\b\1.txt, and some are only simple file names, such as: 1.txt Process the path portion of the file name that gets to the uploaded files, leaving only the file name part of filename = filename.substring (filename.lastindexof ("\ \") +1); Gets the input stream of the uploaded file in item inputstream in = Item.getinputstream (); Create a file output stream FileOutputStream out = new FileOutputStream (savepath + "\ \" + filename); Create a buffer of byte buffer[] = new byte[1024]; Determines whether the data in the input stream has been read out of the identity int len = 0; The loop reads the input stream into the buffer, (len=in.read (buffer)) >0 indicates that there is data while ((Len=in.read (buffer)) >0) { Writes the data of the buffer to the specified directory using the FileOutputStream output stream (SAVEPAth + "\ \" + filename) out.write (buffer, 0, Len); }//Close input stream in.close (); Turn off the output stream out.close (); Delete temporary files generated when processing file uploads item.delete (); message = "File Upload succeeded!" "; }}}catch (Exception e) {message= "File upload failed! "; E.printstacktrace (); } request.setattribute ("message", message); Request.getrequestdispatcher ("/message.jsp"). Forward (request, response); } public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioex ception {doget (request, response); }}
meaasge.jsp after successful upload
<%@ page language= "java" pageencoding= "UTF-8"%><! DOCTYPE html>
Web. XML configuration
xsi:schemalocation= "HTTP://JAVA.SUN.COM/XML/NS/J2EE http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd/http Xmlns.jcp.org/xml/ns/javaee
Http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd "id=" webapp_id "version=" 2.4 "> <display-name> Spring MVC application</display-name> <welcome-file-list> <welcome-file>index.jsp</ Welcome-file> </welcome-file-list></web-app>
Details of File UploadAlthough the above code can successfully upload the file to the server above the specified directory, but the file upload function has a lot of attention to the small details of the problem, the following points out the need to pay special attention to
1, in order to ensure the security of the server, upload files should be placed in the outside world can not directly access the directory, such as placed in the Web-inf directory.
2, in order to prevent file coverage occurs, to upload a file to generate a unique file name.
3, in order to prevent a directory under too many files, to use the hash algorithm to break up storage.
4. To limit the maximum number of uploaded files.
5, to limit the type of uploaded files, when you receive the upload file name, determine whether the suffix is legitimate.
To address the above 5 points of detail, we will improve the Uploadhandleservlet, the improved code is as follows:
Package Servlet;import Java.io.file;import Java.io.fileoutputstream;import java.io.ioexception;import Java.io.inputstream;import Java.util.list;import Java.util.uuid;import Javax.servlet.servletexception;import Javax.servlet.http.httpservlet;import Javax.servlet.http.httpservletrequest;import Javax.servlet.http.httpservletresponse;import Org.apache.commons.fileupload.fileitem;import Org.apache.commons.fileupload.fileuploadbase;import Org.apache.commons.fileupload.progresslistener;import Org.apache.commons.fileupload.disk.diskfileitemfactory;import org.apache.commons.fileupload.servlet.servletfileupload;//using @webservlet to configure Uploadservlet access paths
@WebServlet (name= "Uploadservlet", urlpatterns= "/uploadservlet")
Using annotation @multipartconfig to identify a servlet as a support file upload
@MultipartConfig//Identity servlet support File upload public class Uploadservlet extends HttpServlet {public void doget (httpservletrequest Request, HttpServletResponse response) throws Servletexception, IOException {//Get the saved directory of uploaded files, upload Files are stored in the Web-inf directory, do not allow direct access to the outside world, to ensure the security of uploading files String Savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploa D "); Temporary files generated at upload save directory String TempPath = This.getservletcontext (). Getrealpath ("/web-inf/temp"); File Tmpfile = new file (TempPath); if (!tmpfile.exists ()) {//Create temp directory Tmpfile.mkdir (); }//message prompt String message = ""; try{//Use Apache File Upload component to process file upload steps://1, create a diskfileitemfactory factory Disk Fileitemfactory factory = new Diskfileitemfactory (); Sets the size of the factory buffer, and when the uploaded file size exceeds the size of the buffer, a temporary file is generated to be stored in the specified temporary directory. Factory.setsizethreshold (1024*100)///Set buffer size is 100KB, if not specified, then the size of the buffer default is 10KB//set upload generated when the Save directory for temporary Files factory.setrepository (tmpfile); 2. Create a file upload parser servletfileupload upload = new Servletfileupload (factory); Monitor File Upload Progress Upload.setprogresslistener (new Progresslistener () {public void update (Long pbytesread, long pcontentlength, int arg2) {System.out.println ("File size:" + Pcontentlength + ", currently processed:" + pbytesread); /** * File Size: 14608, currently processed: 4096 file size: 14608, currently processed: 7367 File size: 14608, currently processed: 11419 file Size: 14608, currently processed: 14608 */ } }); Solve the upload file name of the Chinese garbled upload.setheaderencoding ("UTF-8"); 3, determine whether the data submitted is the upload form data if (! Servletfileupload.ismultipartcontent (Request)) {//Get data return in traditional way; }//sets the maximum size of the uploaded individual file, currently set to 1024*1024 bytes, which is 1MB upload . Setfilesizemax (1024*1024); Set the maximum number of uploaded files, max = The sum of the maximum number of simultaneous uploads of multiple files, currently set to 10MB Upload.setsizemax (1024*1024*10); 4, using the Servletfileupload parser to parse the upload data, the results of the analysis returned is a list<fileitem> collection, each fileitem corresponding to a form form input items List<fil eitem> list = upload.parserequest (request); for (Fileitem item:list) {//If the data that is encapsulated in the fileitem is a normal input item if (Item.isformfield ()) { String name = Item.getfieldname (); Solve the problem of normal input data in Chinese garbled String value = item.getstring ("UTF-8"); Value = New String (value.getbytes ("iso8859-1"), "UTF-8"); SYSTEM.OUT.PRINTLN (name + "=" + value); }else{//if the upload file//Get uploaded file name is encapsulated in Fileitem, String filename = item.getn Ame (); SYSTEM.OUT.PRINTLN (filename); if (Filename==null | | Filename.trim (). Equals ("")) {continue; }//Note: Different browser submissions are not the same file name, some browsers submitted by the file name is with a path, such as: C:\a\b\1.txt, and some are only simple file names, such as: 1.txt Process the path portion of the file name that gets to the uploaded files, leaving only the file name part of filename = filename.substring (filename.lastindexof ("\ \") +1); Get the extension of the uploaded file String fileextname = filename.substring (".") (Filename.lastindexof) +1); If you need to limit the file type of the upload, then you can use the file extension to determine whether the uploaded file type is legitimate System.out.println ("The file name extension is:" +fileeXtname); Gets the input stream of the uploaded file in item inputstream in = Item.getinputstream (); Get the file save name String savefilename = makefilename (filename); Get the File save directory String Realsavepath = Makepath (Savefilename, Savepath); Create a file output stream FileOutputStream out = new FileOutputStream (realsavepath + "\ \" + savefilename); Create a buffer of byte buffer[] = new byte[1024]; Determines whether the data in the input stream has been read out of the identity int len = 0; The loop reads the input stream into the buffer, (len=in.read (buffer)) >0 indicates that there is data while ((Len=in.read (buffer)) >0) { Writes the data of the buffer to the specified directory (savepath + "\ \" + filename) using the FileOutputStream output stream Out.write (buffer, 0, Len); }//Close input stream in.close (); Turn off the output stream out.close (); Delete temporary files generated when processing file uploads//item.delete (); message = "File Upload succeeded!" "; }}}catch (Fileuploadbase.filesizelimitexceededexception e) {E.prin Tstacktrace (); Request.setattribute ("Message", "Single file exceeded maximum value!!!") "); Request.getrequestdispatcher ("/message.jsp"). Forward (request, response); Return }catch (fileuploadbase.sizelimitexceededexception e) {e.printstacktrace (); Request.setattribute ("message", "The total size of the uploaded file exceeds the maximum limit!!!") "); Request.getrequestdispatcher ("/message.jsp"). Forward (request, response); Return }catch (Exception e) { message= "File upload failed! "; E.printstacktrace (); } request.setattribute ("message", message); Request.getrequestdispatcher ("/message.jsp"). Forward (request, response); }/** * @Method: Makefilename * @Description: Generate the file name of the uploaded file, file name to: uuid+ "_" + the original name of the file * @param the original name of the filename file * @return Uuid+ "_" + the original name of the file */private string Makefilename (string filename) {//2.jpg//To prevent file overwrite, to upload the file Generates a unique file name for return Uuid.randomuuid (). toString () + "_" + filename; }/** * To prevent too many files appearing under a directory, the hash algorithm is used to break up the storage * @Method: Makepath * @Description: * * @param filename Name, to generate the storage directory according to the file name * @param savepath file storage path * @return New storage Directory */private string Makepath (string filename,string s Avepath) {//Get the Hashcode value of the file name, get the filename of this string object in memory of the address int hashcode = Filename.hashcode (); int dir1 = hashcode&0xf; 0--15 int dir2 = (hashcode&0xf0) >>4; 0-15//Construct a new save directory String dir = savepath + "\ \" + dir1 + "\ \" + Dir2; Upload\2\3 upload\3\5//file can represent either a file or a directory file File = new file (dir); If the directory does not exist if (!file.exists ()) {//Create directory File.mkdirs (); } return dir; } public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioex ception {doget (request, response); }}
File upload and download in Javaweb