File Upload Overview
To realize the file upload function in web development, you need to complete the following two steps :
Add upload input to the web page
Read the uploaded file data in the servlet and save it to the local hard disk.
How to add upload input items to web pages?
The <input type="file"> tag is used to add file upload input items to the web page. You must pay attention to when setting file upload input items:
1. The name attribute of the input input item must be set, otherwise the browser will not send the uploaded file data.
2. The enctype value of form must be set to multipart/form-data. After setting this value, when the browser uploads the file, it will attach the file data to the http request message body, and use the MIME protocol to describe the uploaded file to facilitate the receiver to parse and process the uploaded data.
File Upload Overview
How to read file upload data in Servlet and save it to local hard disk?
The Request object provides a getInputStream method, through which data submitted by the client can be read. However, since users may upload multiple files at the same time, it is a very troublesome job to programmatically read the upload data directly on the servlet side and parse the corresponding file data separately, examples.
To facilitate users to process file upload data, Apache open source organization provides an open source component (Commons-fileupload) used to process form file uploads. This component has excellent performance and its API is extremely simple to use, allowing developers to easily implement web file upload functions. Therefore, the file upload function is usually implemented in web development, which is usually implemented using the Commons-fileupload component.
Use the Commons-fileupload component to implement file upload, and you need to import the corresponding support jar packages for this component: Commons-fileupload and commons-io. commons-io does not belong to the development jar file for file upload components, but the Commons-fileupload component starts with version 1.1 and requires support from the commons-io package when it works.
fileupload component workflow
Core API - DiskFileItemFactory
DiskFileItemFactory is the factory that creates FileItem objects. Common methods for this factory class:
public void setSizeThreshold(int sizeThreshold): Sets the size of the memory buffer, the default value is 10K. When the upload file is larger than the buffer size, the fileupload component will upload the file using a temporary file cache.
public void setRepository(java.io.File repository): Specify the temporary file directory, the default value is System.getProperty("java.io.tmpdir").
public DiskFileItemFactory(int sizeThreshold, java.io.File repository): Constructor
Core API - ServletFileUpload
ServletFileUpload is responsible for processing uploaded file data and encapsulates each input item in the form into a FileItem object. Common methods are:
boolean isMultipartContent(HttpServletRequest request): determines whether the uploaded form is multipart/form-data type
List parseRequest(HttpServletRequest request): parse the request object, wrap each input item in the form into a fileItem object, and return a list collection that saves all FileItems.
setFileSizeMax(long fileSizeMax): Set the maximum value of uploaded files
setSizeMax(long sizeMax): Set the maximum value of the total number of uploaded files
setHeaderEncoding(java.lang.String encoding): Set the encoding format
setProgressListener(ProgressListener pListener)
File upload case
Implementation steps
1. Create a DiskFileItemFactory object, set the buffer size and temporary file directory 2. Use the DiskFileItemFactory object to create a ServletFileUpload object, and set the size limit for uploading files.
3. Call ServletFileUpload.parseRequest method to parse the request object and obtain a List object that saves all uploaded contents.
4. Iterate over the list. Each iterates a FileItem object, and call its isFormField method to determine whether it is an uploaded file.
It is a normal form field, then call getFieldName and getString methods to get the field name and field value
To upload a file, the getInputStream method is called to obtain the data input stream, thereby reading the uploaded data.
Encoding to implement file upload
Processing details of uploading files
Chinese file garbled problem
The problem of garbled Chinese file name, you can call the setHeaderEncoding method of ServletUpLoader, or set the setCharacterEncoding property of the request
Temporary file deletion problem
Since the file size exceeds the size of the memory buffer set by the DiskFileItemFactory.setSizeThreshold method, the Commons-fileupload component will use a temporary file to save the uploaded data. Therefore, at the end of the program, be sure to call the FileItem.delete method to delete the temporary file.
The call to the Delete method must be after the stream is closed, otherwise file usage will occur, resulting in the deletion failure.
File storage location
To ensure the security of the server, the uploaded files should be saved in the WEB-INF directory of the application, or a directory not managed by the WEB server.
To prevent multiple users from uploading files with the same file name, resulting in file overwriting, the file uploader should ensure that the uploaded file has a unique file name.
In order to prevent too many files in a single directory and affect the speed of file reading and writing, the program that handles uploading files should select the appropriate directory structure generation algorithm based on the total amount of possible file uploads, and store the uploaded files in a scattered manner.
File download
Because the file to be downloaded can be of various types, the file must be transferred to the client, and its corresponding content should be processed as binary, so the method should be called to return the ServeltOutputStream object to write the file content to the client.
Download the case
Iterate through all files in the upload directory and displays them to the user and allows the user to complete the download.
(Read all files in a certain folder, save them to the List in the collection, and then save them to the scope of the request) ListFileServlt―(Show all files list) Listfiles.jsp----DownloaServlet.javaprivate String id;private String savename; //The name of the upload file, the uuid name of the file private String realName; //The real name of the upload file private String savepath; //Remember the location of the file private Date uptime; //The upload time of the file private String description; //The description of the file private String username; //The uploader ListFileServletpackage com.hbsi.servlet;import java.io.File;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;public class ListFileServlet extendsHttpServlet {publicvoid doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {Stringsavepath = this.getServletContext().getRealPath("/WEB-INF/upload");Mapmap = new HashMap();listFiles(newFile(savepath), map);request.setAttribute("map",map);request.getRequestDispatcher("/listfile.jsp").forward(request,response);}privatevoid listFiles(File file, Map map) {if(file.isFile()) {Stringuuidname = file.getName(); // uuid_a_1_3_3.txtStringrealname = uuidname.substring(uuidname.indexOf("_") + 1);map.put(uuidname,realname);}else {File[]files = file.listFiles();for(File f : files) {listFiles(f,map);}}}publicvoid doPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {doGet(request,response);}}DownloadServletpackage com.hbsi.servlet;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;public class DownloadServlet extendsHttpServlet {publicvoid doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {Stringfilename = request.getParameter("filename");filename= new String(filename.getBytes("iso8859-1"), "utf-8");System.out.println(filename);Stringsavepath = this.getFileSavePath(this.getRealName(filename));Filef = new File(savepath + "//" + filename);if(!f.exists()) {request.setAttribute("message","The downloaded resource does not exist");request.getRequestDispatcher("/message.jsp").forward(request,response);}response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(this.getRealName(filename),"UTF-8"));FileInputStreamin = new FileInputStream(f);byte[]buf = new byte[1024];intlen = 0;OutputStreamout = response.getOutputStream();while((len = in.read(buf)) > 0) {out.write(buf,0, len);}in.close();}publicString getFileSavePath(String filename) {intdir1 = filename.hashCode() & 0xf;intdir2 = (filename.hashCode() >> 4) & 0xf;Stringsavepath = this.getServletContext().getRealPath("/WEB-INF/upload")+"//" + dir1 + "//" + dir2;returnsavepath;}publicString getRealName(String filename) {StringrealName = filename.substring(filename.indexOf("_") + 1);returnrealName;}publicvoid doPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {doGet(request,response);}}