In the Web application system development, the file upload and download function is very common function, today will talk about the JavaWeb file upload and download function.

For file uploading, the browser submits the file to the server in the form of stream during the upload process. It is troublesome to directly use the Servlet to obtain the input stream of the uploaded file and then parse the request parameters in it. Therefore, apache’s open source tool common-Fileupload is generally used to upload files. The common-fileupload upload jar can be downloaded from the Apache website or found in the Struts lib folder. Struts uploads are based on this implementation. Common-fileupload depends on the common-io package, so you need to download this package.

I. Construction of development environment

Create a FileUploadAndDownLoad project and add the jars for Apache’s commons-fileupload fileupload component, as shown below:

  

Two, to achieve file upload

2.1 File upload page and message prompt page

The code for the upload.jsp page is as follows:

<%@ page language="java" pageEncoding="UTF-8"%>
<! DOCTYPEHTML>
<html>
  <head>
    <title>File upload</title>
  </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="Submit">
    </form>
  </body>
</html>
Copy the code

The code for message.jsp looks like this:

<%@ page language="java" pageEncoding="UTF-8"%>
<! DOCTYPEHTML>
<html>
  <head>
    <title>Message prompt</title>
  </head>
  
  <body>
        ${message}
  </body>
</html>
Copy the code

2.2 servlets handling file uploads

Uploadhandle server vlet code is as follows:

package me.gacl.web.controller;

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.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;

public class UploadHandleServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
                // Obtain the directory for storing the uploaded files and store the uploaded files in the WEB-INF directory. Direct access is prohibited to ensure file security
                String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
                File file = new File(savePath);
                // Check whether the directory for saving the uploaded file exists
                if(! file.exists() && ! file.isDirectory()) { System.out.println(savePath+"Directory does not exist, needs to be created");
                    // Create directory
                    file.mkdir();
                }
                // Message prompt
                String message = "";
                try{
                    // Use the Apache file upload component to upload files.
                    // create a DiskFileItemFactory
                    DiskFileItemFactory factory = new DiskFileItemFactory();
                    // create a file upload parser
                    ServletFileUpload upload = new ServletFileUpload(factory);
                     // Resolve the garbled Chinese characters in the uploaded file name
                    upload.setHeaderEncoding("UTF-8"); 
                    //3. Determine whether the submitted data is the data of the uploaded form
                    if(! ServletFileUpload.isMultipartContent(request)){// Get data in the traditional way
                        return;
                    }
                    // Use the ServletFileUpload parser to parse the uploaded data and return a List
      
        set. Each FileItem corresponds to an input item of the Form
      
                    List<FileItem> list = upload.parseRequest(request);
                    for(FileItem item : list){
                        // If fileItem encapsulates the data of ordinary input items
                        if(item.isFormField()){
                            String name = item.getFieldName();
                            // Solve the problem of garbled Chinese characters in 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 fileItem encapsulates an uploaded file
                            // Get the name of the uploaded file,
                            String filename = item.getName();
                            System.out.println(filename);
                            if(filename==null || filename.trim().equals("")) {continue;
                            }
                            // Note: different browsers submit different file names. Some browsers submit file names with paths, such as c:\a\b\1.txt, while others submit simple file names, such as 1.txt
                            // Process the path part of the file name of the uploaded file, leaving only the file name part
                            filename = filename.substring(filename.lastIndexOf("\ \") +1);
                            // Get the input stream for the uploaded 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];
                            // A flag to determine whether the data in the input stream has been read
                            int len = 0;
                            // Loop the input stream into the buffer, (len=in.read(buffer))>0 means there is data in
                            while((len=in.read(buffer))>0) {// Use FileOutputStream to write buffer data to the specified directory (savePath + "\\" + filename)
                                out.write(buffer, 0, len);
                            }
                            // Close the input stream
                            in.close();
                            // Close the output stream
                            out.close();
                            // Delete temporary files generated while processing file uploads
                            item.delete();
                            message = "File uploaded successfully!"; }}}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, IOException { doGet(request, response); }}Copy the code

Register uploadHandle server in the web. XML file

<servlet>
    <servlet-name>UploadHandleServlet</servlet-name>
    <servlet-class>me.gacl.web.controller.UploadHandleServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>UploadHandleServlet</servlet-name>
    <url-pattern>/servlet/UploadHandleServlet</url-pattern>
</servlet-mapping>
Copy the code

The running effect is as follows:

   

After the file was successfully uploaded, the uploaded file was saved to the upload directory in the WEB-INF directory, as shown in the following figure:

  

2.3 Details of file uploading

While the above code successfully uploads files to the specified directory on the server, there are a number of minor details to pay attention to in the file upload function

1. To ensure server security, upload files to a directory that cannot be accessed directly, for example, the WEB-INF directory.

2. To prevent file overwriting, create a unique file name for the uploaded file.

3. To prevent too many files in a directory, use the hash algorithm to split the storage.

4. Limit the maximum number of uploaded files.

5, to limit the type of the uploaded file, when receiving the uploaded file name, determine whether the suffix is valid.

UploadHandleServlet UploadHandleServlet UploadHandleServlet UploadHandleServlet

package me.gacl.web.controller;

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;

/ * * *@ClassName: UploadHandleServlet
* @Description: TODO(here is a one-sentence description of what this class does) *@author: Lone Wolf *@date: 2015-1-3 11:35:50 * */ 
public class UploadHandleServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
                // Obtain the directory for storing the uploaded files and store the uploaded files in the WEB-INF directory. Direct access is prohibited to ensure file security
                String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
                // Save directory for temporary files generated during upload
                String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
                File tmpFile = new File(tempPath);
                if(! tmpFile.exists()) {// Create a temporary directory
                    tmpFile.mkdir();
                }
                
                // Message prompt
                String message = "";
                try{
                    // Use the Apache file upload component to upload files.
                    // create a DiskFileItemFactory
                    DiskFileItemFactory factory = new DiskFileItemFactory();
                    // Set the size of the factory buffer. If the size of the uploaded file exceeds the size of the buffer, a temporary file will be generated and stored in the specified temporary directory.
                    factory.setSizeThreshold(1024*100);// Set the buffer size to 100KB. If not specified, the default buffer size is 10KB
                    // Set the directory for saving temporary files generated during upload
                    factory.setRepository(tmpFile);
                    // 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 */}});// Resolve the garbled Chinese characters in the uploaded file name
                    upload.setHeaderEncoding("UTF-8"); 
                    //3. Determine whether the submitted data is the data of the uploaded form
                    if(! ServletFileUpload.isMultipartContent(request)){// Get data in the traditional way
                        return;
                    }
                    
                    // Set the maximum size of a single file to be uploaded. Currently, the maximum size is 1024*1024 bytes, i.e. 1MB
                    upload.setFileSizeMax(1024*1024);
                    // set the maximum number of files to be uploaded. The maximum value is the sum of the maximum size of multiple files to be uploaded at the same time. The current value is 10MB
                    upload.setSizeMax(1024*1024*10);
                    // Use the ServletFileUpload parser to parse the uploaded data and return a List
      
        set. Each FileItem corresponds to an input item of the Form
      
                    List<FileItem> list = upload.parseRequest(request);
                    for(FileItem item : list){
                        // If fileItem encapsulates the data of ordinary input items
                        if(item.isFormField()){
                            String name = item.getFieldName();
                            // Solve the problem of garbled Chinese characters in 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 fileItem encapsulates an uploaded file
                            // Get the name of the uploaded file,
                            String filename = item.getName();
                            System.out.println(filename);
                            if(filename==null || filename.trim().equals("")) {continue;
                            }
                            // Note: different browsers submit different file names. Some browsers submit file names with paths, such as c:\a\b\1.txt, while others submit simple file names, such as 1.txt
                            // Process the path part of the file name of the uploaded file, leaving only the file name part
                            filename = filename.substring(filename.lastIndexOf("\ \") +1);
                            // Get the extension of the uploaded file
                            String fileExtName = filename.substring(filename.lastIndexOf(".") +1);
                            // If you want to limit the type of files to be uploaded, you can use the file extension to determine whether the uploaded file type is valid
                            System.out.println("The extension of the uploaded file is:"+fileExtName);
                            // Get the input stream for the uploaded file in item
                            InputStream in = item.getInputStream();
                            // Get the name of the file to save
                            String saveFilename = makeFileName(filename);
                            // Get the directory to save the file
                            String realSavePath = makePath(saveFilename, savePath);
                            // Create a file output stream
                            FileOutputStream out = new FileOutputStream(realSavePath + "\ \" + saveFilename);
                            // Create a buffer
                            byte buffer[] = new byte[1024];
                            // A flag to determine whether the data in the input stream has been read
                            int len = 0;
                            // Loop the input stream into the buffer, (len=in.read(buffer))>0 means there is data in
                            while((len=in.read(buffer))>0) {// Use FileOutputStream to write buffer data to the specified directory (savePath + "\\" + filename)
                                out.write(buffer, 0, len);
                            }
                            // Close the input stream
                            in.close();
                            // Close the output stream
                            out.close();
                            // Delete temporary files generated while processing file uploads
                            //item.delete();
                            message = "File uploaded successfully!"; }}}catch (FileUploadBase.FileSizeLimitExceededException e) {
                    e.printStackTrace();
                    request.setAttribute("message"."Single file exceeds maximum!!");
                    request.getRequestDispatcher("/message.jsp").forward(request, response);
                    return;
                }catch (FileUploadBase.SizeLimitExceededException e) {
                    e.printStackTrace();
                    request.setAttribute("message"."Total uploaded file size 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: Specifies the name of the file to be uploaded in the following format: uuid+"_"+ original file name *@Anthor: Lone Wolf *@paramFilename The original name of the file *@returnUuid +"_"+ the original file name */ 
    private String makeFileName(String filename){  //2.jpg
        // To prevent file overwriting, create a unique file name for the uploaded file
        return UUID.randomUUID().toString() + "_" + filename;
    }
    
    /** * To prevent too many files under a directory, use the hash algorithm to break up the storage *@Method: makePath
    * @Description: 
    * @AnthorLone Wolf * *@paramFilename specifies the filename, based on which a storage directory is generated@paramSavePath File storage path *@returnNew storage directory */ 
    private String makePath(String filename,String savePath){
        // Get the hashCode value of the filename, which is the memory address of the string object filename
        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 be 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, IOException { doGet(request, response); }}Copy the code

After improving the above mentioned 5 small details, our file upload function is relatively complete.

File download

3.1 list the file resources available for download

We want to provide the file resources in the Web application system for users to download. First of all, we want to have a page listing all the files under the directory of uploaded files. When the user clicks the hyperlink to download files, the download operation will be carried out.

The code for ListFileServlet is as follows:

package me.gacl.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/ * * *@ClassName: ListFileServlet
* @Description: Lists all downloaded files in the Web system *@author: Lone Wolf *@date: 2015-1-4 9:54:40 * */ 
public class ListFileServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Get the directory to upload the file
        String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        // Store the file name to download
        Map<String,String> fileNameMap = new HashMap<String,String>();
        // Recursively traverses all files and directories in the filepath directory, storing the file names into the map collection
        listfile(new File(uploadFilePath),fileNameMap);//File can represent either a File or a directory
        // Send the Map collection to the listfile.jsp page for display
        request.setAttribute("fileNameMap", fileNameMap);
        request.getRequestDispatcher("/listfile.jsp").forward(request, response);
    }
    
    / * * *@Method: listfile
    * @Description: recursively traverses all files in the specified directory *@Anthor: Lone Wolf *@paramFile is a file and a file directory *@paramMap Map collection of file names */ 
    public void listfile(File file,Map<String,String> map){
        // If file is not a file, but a directory
        if(! file.isFile()){// Lists all files and directories under this directory
            File files[] = file.listFiles();
            // Iterate through the files[] array
            for(File f : files){
                / / recursionlistfile(f,map); }}else{
            IndexOf ("_") retrieves the position in the string where the "_" character first appears if the filename is similar to: Avi file file.getName().substring(file.getName().indexof ("_")+1) */
            String realName = file.getName().substring(file.getName().indexOf("_") +1);
            //file.getName() returns the original name of the file. This name is unique and therefore can be used as the key. RealName is the processed name and may be duplicatedmap.put(file.getName(), realName); }}public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException { doGet(request, response); }}Copy the code

The listFile method is used to list all files in the directory. The listFile method uses recursion internally. In the actual development, we will definitely create a table in the database. Will be stored inside the upload file name and file storage directory, we can know the specific file through the query table storage directory, is not to need to use recursive operations, this example because no upload using a database to store the file name and file location, and upload file location using the hash algorithm scattered storage, So recursion is needed, and in recursion, the obtained file name is stored in the Map set passed to the listFile method, so that all files are stored in the same Map set.

Configure the ListFileServlet in the web.xml file

<servlet>
     <servlet-name>ListFileServlet</servlet-name>
     <servlet-class>me.gacl.web.controller.ListFileServlet</servlet-class>
</servlet>
 
<servlet-mapping>
     <servlet-name>ListFileServlet</servlet-name>
    <url-pattern>/servlet/ListFileServlet</url-pattern>
</servlet-mapping>
Copy the code

The listfile.jsp page showing the downloaded file looks like this:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<! DOCTYPEHTML>
<html>
  <head>
    <title>Download file display page</title>
  </head>
  
  <body>
      <! Map collection -->
    <c:forEach var="me" items="${fileNameMap}">
        <c:url value="/servlet/DownLoadServlet" var="downurl">
            <c:param name="filename" value="${me.key}"></c:param>
        </c:url>
        ${me.value}<a href="${downurl}">download</a>
        <br/>
    </c:forEach>
  </body>
</html>
Copy the code

To access the ListFileServlet, the listfile.jsp page displays the file resources provided to the user for download, as shown below:

  

3.2. Download files

Write a Servlet to handle file downloads. The code for DownLoadServlet is as follows:

package me.gacl.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DownLoadServlet extends HttpServlet {

    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Get the file name to download
        String fileName = request.getParameter("filename");  //23239283-92489- Avatar.avi
        fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
        // Uploads are stored in subdirectories under the/web-INF /upload directory
        String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
        // Find the directory where the file is located
        String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
        // Get the file to download
        File file = new File(path + "\ \" + fileName);
        // If the file does not exist
        if(! file.exists()){ request.setAttribute("message"."The resource you want to download has been deleted!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        }
        // Process the file name
        String realname = fileName.substring(fileName.indexOf("_") +1);
        // Set the response header to control the browser to download the file
        response.setHeader("content-disposition"."attachment; filename=" + URLEncoder.encode(realname, "UTF-8"));
        // Read the file to download and save it to the file input stream
        FileInputStream in = new FileInputStream(path + "\ \" + fileName);
        // Create an output stream
        OutputStream out = response.getOutputStream();
        // Create buffer
        byte buffer[] = new byte[1024];
        int len = 0;
        // The loop reads the contents of the input stream into the buffer
        while((len=in.read(buffer))>0) {// Outputs the contents of the buffer to the browser for file download
            out.write(buffer, 0, len);
        }
        // Close the file input stream
        in.close();
        // Close the output stream
        out.close();
    }
    
    / * * *@Method: findFileSavePathByFileName
    * @Description: Find the path of the file you want to download by referring to the file name and the root directory of the uploaded file@Anthor: Lone Wolf *@paramFilename filename to download *@paramSaveRootPath = / web-INF /upload *@returnThe directory where the files to be downloaded are stored */ 
    public String findFileSavePathByFileName(String filename,String saveRootPath){
        int hashcode = filename.hashCode();
        int dir1 = hashcode&0xf;  / / 0-15
        int dir2 = (hashcode&0xf0) > >4;  / / 0-15
        String dir = saveRootPath + "\ \" + dir1 + "\ \" + dir2;  //upload\2\3 upload\3\5
        File file = new File(dir);
        if(! file.exists()){// Create directory
            file.mkdirs();
        }
        return dir;
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException { doGet(request, response); }}Copy the code

Configure the DownLoadServlet in the web.xml file

<servlet>
      <servlet-name>DownLoadServlet</servlet-name>
      <servlet-class>me.gacl.web.controller.DownLoadServlet</servlet-class>
</servlet>
 
<servlet-mapping>
      <servlet-name>DownLoadServlet</servlet-name>
      <url-pattern>/servlet/DownLoadServlet</url-pattern>
</servlet-mapping>
Copy the code

Click the hyperlink [Download], submit the request to DownLoadServlet for processing, and you can download the file. The running effect is as shown in the picture below:

  

It can be seen from the running result that our file download function can download files normally.

So much for the file upload and download capabilities in JavaWeb.

From: www.cnblogs.com/xdp-gacl/p/…