In the development of web application system, the file upload and download function of the file are very commonly used. Today, let's talk about the implementation of the file upload and download function in JavaWeb.
For file upload, the browser submits the file to the server side during the upload of the browser. If it is directly used to use the service to obtain the input stream of the upload file, and then analyze the request parameter in the inside is more troublesome, so generally you choose to use Apache’s Apache’s of the Apache. Open source tool Common-Fileupload this file upload component. This Common-Fileupload upload component's jar package can be downloaded on the Apache official website, or you can find it under the Struts lib folder. The function uploaded by Struts is based on this. Common-Fileupload depends on the COMMON-IO package, so you need to download this package.
1. Development environment Construction
Create a FileupLoadandDownload project, add Apache Commons-Fileupload file to upload the related jar package of the component, as shown in the figure below:
2. Implement file upload
2.1, file upload page and message prompt page
The code of the upload.jsp page is as follows:
<%@ page language = "java" pageEncoding = "UTF-8"%> <! Doctype html> <HEAD> <Title> File Upload </Head> <body> <FORM ACTION = " $ {PageContext.request.ContextPath}/Servlet/UPLOADHANDLESERVLET "EnCTYPE =" Multipart/Form-Data "METHOD =" Post "> Upload User: <input Type =" Text "Name = "Username"> <br/> Upload file 1: <input type = "file" name = "file1"> <br/> Upload file 2: <input type = "file" name = "file2"> <br/> <input type = "submit" value = "value =" Submit "</form> </body> </html>
Message.jsp's code is as follows:
<%@ page language = "java" pageencoding = "utf-8"%> <! Doctype html> <head> <Title> Message </head> <body> $ {Message} /body> </html>
2.2, handle the service uploaded by the file
The code of uploadhandleServlet is as follows:
package me.gacl.web.controller; Import Java.iO.File; Import Java.FileoutPutstream; Import java.io.ioException; mport java.util.list; Import javax.servlet.servletexception ; Import javax.servlet.http.httpservlet; Import javax.servlet.httpServletRequest; Import javax.servlet.httpservletResponse; Chemons.fileupload.fileIitem; Import org.apache.commons.fileupload.disk. DiskFileItemFactory; Import org.apache.commons.fileupload.servletFileupload; Public Class Upload Extends HTTPSERVLET {Public OID DOGET (httpservletRequest request, httpservletResponse Response) Throws ServLetexception, IOEXCEPTION {// Wet the preservation directory of the uploaded file, and store the uploaded files In the web-inf directory, it is not allowed to be accessed directly to ensure that the safe string savepath = this.GetServletContext (). GetRealPath ("/Web-inF/UPLOAD"); File File = New File (SAVEPATH); // Determine whether the preservation directory of upload files exists if (! File.exists () &&! File.isdirectory ()) {System.out.println (Savepath+"directory does not exist, you need to create"); // Create the directory File.mkdir ( );} // Message prompt String Message = "" ""; try {// Use Apache file to upload component processing file Upload steps: // 1. Create a DiskFileiteMFactory factory DiskFileIIITEMFACTORY = NewFileItem Factor (); // 2. Create a file Upload the parser ServletFileupload upload = New ServletFileupload (Factory); // Solve the Chinese garbled code UPLOAD.SetheaderEncoding of upload file names ("UTF-8"). Data if (! ServletFileupload.ismultipartContent (Request) {// Obtain data Return according to the traditional way;} // 4. Use the serviceFileupload parser to analyze and upload data. M corresponds to a form form Input item list <fileitem> list = upload.parserequest (request); for (fileitem item: list) {// If the data encapsulated by ordinary input item if (item.isformfield ())) {string name = item. getfieldname (); // The Chinese garbled problem with the data of the data of ordinary input items string value = item.getString ("UTF-8"); // Value = New String (Value.getBytes ("ISO8859-1"), "UTF -8 "); System.out.println (name +" = " + value);} Else {// If the encapsulated file is encapsulated in the fileitem, the name of the uploaded file, string filename = item.getName (); System.out.println (FILENAME); if (filename == NULL || FILENAME.TRIM (). Equals ("") {Continue;} // Note: The file names submitted by different browsers are different, Some browsers submit the file names with paths, such as: C: /a/b/1.txt, and some are just simple file names, such as: 1.txt // processing In the path of the name, only the file name part Filename = FILENAME.SUBSTRING (filename.lastindexof ("//"); // Get the input stream in the upload file in Item inputStream in = item.getinputstream ();/ /Create a file output stream FileoutPutstream out = New FileoutputStream (Savepath + "//" + Filename); // Create a buffer byte buffer [] = new byte [1024] ;//// determine whether the data in the input stream has read The finished logo int len = 0; // The cycle will be read flowing into the buffer, (len = in.read (buffer))> 0 means that there is data space in in )> 0) {// Write the data of the buffer into the specified directory (SAVEPATH + "//" + FILENAME) using the FileoutPutstream output stream. Stream in.close (); // Turn off the output stream out.close (); // Delete the temporary file itm.delete () generated when the processing file is uploaded. ";}}} Catch (Exception E) {message =" File upload failed! "; E.printstacktrace ();} Request.Setattribute (" Message ", Message); Request.getRequestDispatcher ("/Message.jsp "). ;} Public void dopost (httpservletRequest request, httpservletResponse response) Throws ServLetexception, IOEXception {Doget (Request, Response);}}
Register UPLOADHANDLESERVLET in the web.xml file
<Servlet> <Servlet-name> UPLOADHANDLESERVLET </Servlet-Name> <Servlet-Class> Me.gacl.Web.Controller.uploadLeservlet </Servlet-Class> </Servlet> <Serv> let-mapping> <Servlet-name> uploadhandleServlet </Servlet-name> <url-Pattern>/Servlet/UploadhandleServlet </url-Pattern> </Servlet-MAPPING>
The running effect is as follows:
After the file is successfully uploaded, the uploaded file is stored in the UPLOAD directory in the web-inf directory, as shown in the figure below:
2.3. Details of file upload
Although the above code can be successfully uploaded to the designated directory on the server, there are many small details that need attention to the file upload function.
1. In order to ensure the security of the server, the upload file should be placed in the directory that the outside world cannot directly access, such as in the web-inf directory.
2. In order to prevent the file coverage, it is necessary to generate a unique file name for uploading files.
3. To prevent too many files under a directory, use the Hash algorithm to disperse storage.
4. Limit the maximum value of upload files.
5. It is necessary to limit the type of upload files. When receiving the name of upload files, judge whether the gold is legal.
In response to the 5 details of the above, let's improve the UPLOADHANDLESERVLET. The improved code is as follows:
package me.gacl.web.controller; Import java.io.file; Import Java.fileoutPutstream; Import java.io.ioException; Import Java.Io.inputStream; I mport java.util.list; Import java.util.uuid ; Import javax.servlet.servletException; Import javax.servlet.httpServlet; Import javax.Servlet.httpServletRequest; Import TP.HTTPSERVLETRESPONSE; Import org.apache.commons.fileupload.FileIItem; Import org.apache .Commons.fileupload.fileuploadBase; Import org.apache.commons.fileupload.progressListener; Import EmFactory; Import org.apache.comMons.fileupload.servletFileupload; /*** @ClassName : UPLOADHANDLESERVLET * @Descripting: Todo (here to describe the role of this class in one sentence) * @Author: Availability Wolf * @Date: 2015-1-3 PM 11:35:50 * */ Public Class Upload EX. Tends httpservlet {public Void Doget (httpservletRequest request, httpservletResponse Response) Throws ServLetexception, IOEXCEPTION {// The preservation directory of upload files is stored in the Web-INF directory. Direct access to the world to ensure the safe string savepath = this .getServletContext (). GetRealPath ("/Web-inF/Upload"); // The temporary file generated when upload saves the directory string testh = this.getServletContext (). "); File TMPFILE = New File (Temppath); if (! tmpfile.exists ()) {// Create a temporary directory tmpfile.mkdir ();} // Message prompt string message = "" "" ""; try {// Use Apache file to upload component file processing files Upload steps: // 1. Create a DiskFileIItemFactory factory DiskFileIITEMFACTORY FACTORY = New DiskFileIItemFactory (); // Set the size of the buffer of the factory. When the size of the uploaded file exceeds the size of the buffer, a temporary file will be generated. Store to specified In the temporary directory. Factory.setSizethreshold (1024*100); // Set the size of the buffer is 100KB. If it is not specified, the size of the buffer area is 10kb // Setting of the temporary file generated during uploading Factory.setRepository (TMPFILE) // 2. Create a file to upload the parser service servicefileupload upload = new serviceFileupload (factory); // The listening file uploads progress upload.setprogressListener (New ProgressListener () {publicic Void Update (Long PbytesRead, Long PContentLength, int ARG2) {System. out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead); /** * 文件大小为:14608,当前已处理:4096 文件大小为:14608,当前已处理:7367 The size of the file is: 14608, the current processing: 11419 file size is: 14608, currently processed: 14608 */}}); // solve the Chinese garbled in the uploaded file name upload.setHetheaderEncoding ("UTF-8"); // 3. Determine whether the data submitted is the data if (! ServletFileupload.ISMULTIPARTCONT (request)) {// Obtain the data Return in traditional way; 1024*1024 bytes, that is, 1MB UPLOAD.SETFILESIZEMAX (1024*1024); // Set the maximum value of the total amount of upload files, the maximum value of the maximum value of multiple files uploaded at the same time. upload.setSizeMax(1024*1024*10); //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项List<FileItem> list = Upload.parserequest (request); for (Fileitem item: list) {// If it is encapsulated in the fileitem, the data of ordinary input items is (Itemformfield ()) {string name = item.GetFieldName (). ; // Solution The Chinese garbled problem of the data of the ordinary input item string value = item.getstring ("uTF-8"); // value = New String (Value.getBytes ("ISO8859-1"), "UTF-8"); System. out.println (name + "=" + value);} else {// If the file name is uploaded by the uploaded file in the fileitem, string filename = item.getname (); E ); Filename == NULL || Filename.trim (). Equals ("") {Continue;} // Note: The file names submitted by different browsers are different, some files submitted by browsers The name is with the path, such as: C: /a/b/1.txt, and some are just simple file names, such as: 1.txt // processing the file name of the file name of the uploaded file obtained, only retain only Filename = FILENAME.Substring (Filename.lastindexof ("//"); // Get the extension of the uploaded file String FileExtName = FILENAME.SUBSTRING (filename.lastindexof (".. ") +1); / /If you need to limit the file type uploaded, you can determine whether the file type that uploads the file type is legal system.out.println ("the extension of the uploaded file is:"+FileExtName); // Get the in ITEM Input stream of upload files inputStream in = item.getinputstream (); // The name of the file saved by the file is string Savefilename = Makefilename (filename); Epath (Savefilename, Savepath); // Create a File output stream FileoutPutstream out = new fileoutputstream (reaLSAVEPATH + "//" + Savefilename); // Create a buffer byte buffer [] = New byte [1024]; // determine whether the data in the input stream has finished reading. Identification int len = 0; // Read the input flow into the buffer, (len = in.read (buffer))> 0 indicates that there is a data while ((len = in.read (buffer))>> 0) {// Write the data of the buffer into the specified directory (Savepath + "//" + FILENAME) using the FileoutPutstream output stream. close (); // Turn off the output stream out.close (); // Delete the temporary file generated when the processing file is uploaded //item.delete (); MESSAGE = "file upload successfully! ";}}} Catch (FileuploadBase.FileSizelimitexcexception E) {e.printstacktrace (); Request.Setattribute (" Message "," A single file exceeds the maximum value !!! ") ; Request.getRequestdispatcher ("/Message.jsp") .Forward (request, response); Return;} Catch (FileuploadBase.SizelimitexceException E) {e.printstacktrace (); Age "," The total size of the upload file is beyond 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 "). ;} /** * @Method: Makefilename * @ @ Descripting: Generate the file name of the upload file, the file name is: UUID+"_"+file's original name* @Anthor: The original name of the lonely proud wolf* @param Filename file* @Return uuid+"_"+the original name of the file* /Private String Makefilename (String Filename) {//2.jpg // To prevent file coverage, it is necessary to generate a unique file name Return UUID.RANDOMUUID (). Tostring () + " + FILENAME ;} /** * In order to prevent too many files under a directory, use the Hash algorithm to disperse storage * @Method: Makepath * @Description: * @ANTHOR: The Available Wolf * @Param Filename file name, according to the file Name generating storage directory* @Param Savepath file Storage path* @Return new storage directory*/Private String Makepath (String Filename, String Savepath) {// The value of the HashCode of the file name is FILENAM E -string object in this The address of the memory int HashCode = FILENAME.hashcode (); int Dir1 = HashCode & 0XF; // 0--15 int Dir2 = (havecode & 0xf0) >> 4; // 0-15 // Savepath + "//" + dir1 + "//" + dir2; // upload/2/3 upload/3/5 // file can represent the file or the directory file file = new file (dir); // If if The directory does not exist if (! File.exist ()) {// Create the directory file.mkdirs ();} Return Dir;} Public void dopost (httpservletRequest, httpservletresponse response) Servletexception, IOEXception {Doget (Request, Response); }}
After improved the above 5 small details raised, our file upload function is more complete.
Three, file download
3.1. List the file resources to provide downloads
We need to provide the file resources in the web application system to the user to download. First of all, we must have a page to list all the files in the upload file directory. When the user clicks the file to download the hyperlink, the download operation is performed. List all the download files in the web application system.
The code of listFileServlet is as follows:
package me.gacl.web.controller; Import java.io.file; Import Java.io.ioException; Import Java.util.hashmap; Import Java.MAP; Import ax.servlet.servletexception; Import javax.servlet.http .HttpServlet; Import Javax.servlet.httpStpservletRequest; Import Javax.servlet.httpServletResponse;/*** @ClassName: ListFileServlet* CRIPTION: List all the download files in the web system* @Author: The Available Wolf* @ @ Date: 2015-1-4 9:54:40 **/ Public Class ListFileServlet Extends httpservlet {Public Void Doget (httpservletRequest request, httpservletResponse) OWS ServLetexception, IOEXCEPTION {// Get the directory of upload file String uploadFilepath = This.GetServletContext () .GetRealPath ("/Web-inf/Upload"); // Store the file name Map <string, String> FILENAMEMAP = New HashMap <string, String> (); Files and directory, store the file name of the file into the listfile (new file (new filepilepath), filenamemap); // File can represent both a file or a directory // Send the map collection to the listfile.jsp page for Show request.settattribute ("" Filenamemap ", Filenamemap); Request.getRequestdispatcher ("/ListFile.jsp "). Forward (request, response);}/*** @Method: listfile* @Descripting: Recursive traversal in the specified directory All files* @ANTHOR: The Available Wolf* @Param File means a file, and it also represents a file directory* @Param map storage file name MAP collection*/ public void listfile (FILE FILE, MAP <STRING, STRING> Map) {// If file represents not a file, but a directory if (! File.isfile ()) {// List all files and directory in the directory file files [] = file.listfiles (); // Traversing the Files [] array for (file f: files) {// Recursive listfile (f, map);}} Else {/*** processing file name, the uploaded file is renamed in the form of UUID_ file name to rename In the UUID_ part of the file name file.getName (). Indexof ("_") The first "_" character position appeared in the string of the string. If the file name is similar to: 9349249849-88343-8344 Fanda .avi, then file.getName (). Substring (file.getName (). Indexof ("_")+1 can get A _ Fan _ 达 .avi part*/String Realname = File.getName () .substring (file.getName (). Indexof ("_")+1); // file.getName () gets the original name of the file. The name of the later may repeat Map.put (file.getName ()), RealName);}} Public Void Void Dopost (httpservletRequest Request, httpservletResponse) Tion, iOexception {Doget (Request, Response);}}
Here is a brief talk about the listfile method in ListFileServlet. The listfile method is used to list all files in the directory. The listfile method is used internally. The file name and the specific storage directory of the file, we can know the specific storage directory of the file through the query form. It is not necessary to use recursive operations. This example is because the specific storage of file names and files uploaded uploaded by database storage is not needed. The storage position of the uploaded files uses the laidial algorithm and stored, so it needs to be used for recursion. When recursively, the obtained file name is stored in the MAP collection from the outside to the ListFile method. The files are stored in the same MAP collection.
Configure ListFileServlet in the web.xml file
<Servlet> <Servlet-name> ListFileServlet </Servlet-Name> <Servlet-Class> ME.GAC L.Web.Controller.ListFileServlet </Servlet-Class> </Servlet-Mapping> <servlet-name> listfileServlet </Servlet-name> <url-Pattern>/Servlet/ListFileServlet </url-Pattern> </Servlet-Mapping>
The listfile.jsp page of the download file is as follows: as follows:
<%@ page language = "java" image = "java.util.*" pageEncoding = "UTF-8"%> <%@ taglib prefix = "c" uri = "http://java.sun.com/jsp /jstl/core " %> <! DOCTYPE HTML> <HTML> <Head> <Title> Download file display page </title> </head> <body> <!-Traversing MAP collection-> <c: foreach var = "Me" items = "$ {FILENAMEMAP}"> <c: url value = "/server/doubledservlet" var = "double"> <c: param name = "fileename =" $ {me.Key } "> </c: Param> </c: url> $ {me.value} <a href =" $ {doublel} "> Download </a> <br/> </c: foreach> </body> </html>
Visit ListFileServlet, you can display the file resources provided to the user in the listfile.jsp page, as shown in the figure below::
3.2. Implement file download
Write a Servlet for processing files. The code of downloadServlet is as follows: as follows:
package me.gacl.web.controller; Import java.io.file; Import Java.FileInputStream; Import java.io.ioxception; mport java.net.urlencoder; Import javax.servlet.servletexception ; Import javax.servlet.http.httpservlet; Import javax.servlet.httpServletRequest; Import javax.servlet.httpservletResponse; OwnloadServlet Extends httpservlet {Public Void Doget (httpservletRequest Request, httpservletResponse)) Throws service, IOEXCEPTION {////// /Get the file name String Filename = request.getparameter ("FILENAME"); // 23239283-92489- Avatar .avifilename = New (FILENAME.GetBytes ("ISO8859-1"), "UTF-8"); // The files uploaded are all stored in the sub-directory in the/web-inf/upload directory. Where is the directory string path = FindFilesavepathbyfilename (filename, filesaverootpath); // Get the files to be downloaded file file = new file (path + "//" + filename); // If the file does not exist if (! xists () ) {Request.Setattribute ("MESSAGE", "The resources you want to download have been deleted!"); Request.getRequestdispatcher ("/Message.jsp"). Forward (request, response); Processing file Name String realName = FILENAME.SUBSTRING (FILENAME.INDEXOF ("_")+1); // Set the response header, control the browser to download the file Response.Setheader filename = " + urlencoder .encode (realName, "UTF-8"); // Read the files to be downloaded, save to file input stream FileInputStream in = New FileInputstream (PATH + "//" + Filename); // Create output stream outputStream Out = response.getputstream (); // Create a buffer byte buffer [] = new byte [1024]; int len = 0; // The content of the input stream reads the input stream in the buffer ((len = in. Read (buffer))> 0) {// The content of the output buffer to the browser, implement the file download out.write (buffer, 0, len);} // Close the file input flow in.close (); // Close Output stream out.close ();}/*** @Method: FindFilesavepathByFilename* @Description: Find the path of the file to the file to be downloaded through the file name and storage of the file root directory* @AnThor: e The downloaded file name* @Param saverootpath upload the root directory saved by the file, that is, the storage directory of the files to be downloaded by/web-inf/upload directory* @Return to the download file to be downloaded*/Public String FindFilesaVeppiLename (String Filename, S TRING SAVEROOTPATH) {int HashCode = Filename.hashcode (); int Dir1 = HashCode & 0xf; // 0--15INT DIR2 = (HashCode & 0xf0) >> 4; // 0-15String DIR = Saveroolpath + "//" + DIR1 + "//" // "" + D IR2; / /upload/2/3 upload/3/5file file = new file (dir); if (! file.exists ()) {// Create a directory file.mkdirs ();} Return Dir;} Public void UEST Request , HTTPSERVLESPONSE Response) Throws ServLetexception, IOEXCEPTION {Doget (Request, Response);}}
Configure downloadServlet in the web.xml file
<Servlet> <Servlet-name> DownloadServlet </Servlet-Name> <Servlet-Class> Me.g ACL.WEB.Controller.downloadServlet </Servlet-CLASS> </Servlet> <Servlet-Map-Map-Map ping> <Servlet-name> downloadServlet </Servlet-name> <url-Pattern>/Servlet/DOWNLOADSERVLET </url-Pattern> </Servlet-MAPPING>
Click [Download] hyperlink, submit the request to DOWNLOADSERVLET to process it, you can download the file download. The operating effect is shown in the figure below:
From the results of the operation, we can see that our file download function can already download the file normally.
This article has been compiled to "Java Upload Operation Skills", welcome everyone to learn and read.
There are so many contents about file uploading and downloading functions in Javaweb.