File upload and download

File upload and download

File upload and download are very common functions. Many systems or software often use file upload and download.

For example:

QQ avatar is uploaded.

The mailbox also has the function of uploading and downloading attachments.

Upload of approved attachment materials in OA system.

File upload

  1. To have a form tag, method=post request
  2. The value of the encType attribute of the form tag must be a multipart / form data value
  3. Use input type=file in the form tag to add the uploaded file
  4. Write server code (Servlet program) to receive and process the uploaded data.

Enctype = multipart / form data indicates the submitted data, which is spliced in the form of multiple segments (one data segment for each form item), and then sent to the server in the form of binary stream

commons-fileupload.jar common API introduction

commons-fileupload.jar needs to rely on Commons io Jar package, so we need to introduce both packages.

commons-fileupload.jar and Commons io In the jar package, what are the commonly used classes?

  • The ServletFileUpload class is used to parse the uploaded data.

  • FileItem class, representing each form item.

  • boolean ServletFileUpload.isMultipartContent(HttpServletRequest request);

  • Judge whether the currently uploaded data format is multi segment format.

  • public List< FileItem > parseRequest(HttpServletRequest request)

  • Analyze uploaded data

  • boolean FileItem.isFormField()

  • Judge whether the current form item is an ordinary form item. Or the type of file uploaded.

  • true indicates a common type of form item

  • false indicates the type of file uploaded

  • String FileItem.getFieldName()

  • Gets the value of the name attribute of the form item

  • String FileItem.getString()

  • Gets the value of the current form item.

  • String FileItem.getName();

  • Get the uploaded file name

  • void FileItem.write( file );

  • Write the uploaded file to the hard disk location pointed to by the parameter file.

Use of fileupload class library

Form for uploading files:

<form action="http://localhost:8080/05_EL_JSTL/upload" method="post" enctype="multipart/form-data">
        user name:<input type="text" name="username"><br>
        head portrait:<input type="file" name="phtot"><br>
        <input type="submit" value="upload">
  </form>

Code for parsing uploaded data:

public class UploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1. Judge whether the uploaded data is multi segment, and the multi segment data is the file uploaded
        if(ServletFileUpload.isMultipartContent(request)){
            //2. Create FileItemFactory factory implementation class
            FileItemFactory dfif = new DiskFileItemFactory();
            //3. Create a tool class ServletFileUpload class for parsing uploaded data
            ServletFileUpload sfu = new ServletFileUpload(dfif);
            //4. Parse the uploaded data to get each form item FileItem
            try {
                List<FileItem> list = sfu.parseRequest(request);
                //5. Cycle to judge whether each form item is a common type or an uploaded file
                for (FileItem fileItem : list) {
                    if(fileItem.isFormField()){
                        //Normal form
                        System.out.println("Of form items name Attribute value:"+fileItem.getFieldName());
                        //UTF-8 solves garbled code
                        System.out.println("Of form items value Attribute value:"+fileItem.getString("UTF-8"));
                    }else{
                        System.out.println("Uploaded name Attribute value:"+fileItem.getFieldName());
                        System.out.println("Uploaded file name:"+fileItem.getName());
                        try {
                            fileItem.write(new File("E:\\"+fileItem.getName()));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            }

        }

    }
}

File download

Common API descriptions downloaded:

  1. response.getOutputStream();
  2. servletContext.getResourceAsStream();
  3. servletContext.getMimeType();
  4. response.setContentType();

response.setHeader("Content-Disposition", "attachment; fileName=1.jpg");

This response header tells the browser. This needs to be downloaded. Attachment refers to an attachment, that is, a downloaded file. fileName = is followed by the name of the downloaded file.

After completing the above two steps, there is no problem downloading the file. But if the file we want to download is Chinese name. You will find that the download is not correct

The correct Chinese name is displayed because the response header cannot contain Chinese characters, but only ASCII code.

public class DownLoadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. Get the file name to download
        String downLoadFileName = "test.png";
        //2. Read the content to be downloaded, which can be read through the servletContext object
        ServletContext servletContext = getServletContext();
        //3. Get the file type to download
        String mimeType = servletContext.getMimeType("/file/"+downLoadFileName);
        System.out.println("type:"+mimeType);
        //4. Set the response header to tell the client the returned data type
        response.setContentType(mimeType);
        //5. Tell the client that the data received is for downloading (if not set, it will be displayed directly)
        //The corresponding header of content disposition indicates how to handle the received data
        //Attachment means attachment
        //fileName indicates the file name of the specified download
        response.setHeader("Content-Disposition","attachment; fileName=test.png");
            // /The slash is resolved by the server to indicate that the address is http://ip:port/ Project name / web Directory mapped to code
        InputStream resourceAsStream = servletContext.getResourceAsStream("/file/"+downLoadFileName);
        //6. Obtain the corresponding output stream
        OutputStream outputStream = response.getOutputStream();
        //7. Read all data in the input stream, copy it to the output stream and output it to the client
        IOUtils.copy(resourceAsStream, outputStream);
    }
}

Attachment Chinese name garbled code solution

Scheme I

URLEncoder

// UTF-8 encoding the Chinese name.
String str = "attachment; fileName=" + URLEncoder.encode("chinese.jpg", "UTF-8");
// Then set the encoded string into the response header
response.setHeader("Content-Disposition", str);

Scheme II

At this time, the request header content disposition: attachment; Filename = Chinese name

The code becomes: content disposition: attachment; filename==? charset? B? xxxxx?=

=?charset?B?xxxxx?= Now let's explain this paragraph.
=? Indicates the beginning of the encoded content
charset B Represents a character set, B express BASE64 code
xxxx Represents the file name BASE64 Encoded content 
?= Indicates the end of the encoded content

BASE64Encoder:

// After BASE64 encoding using the following format
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode("chinese.jpg".getBytes("utf-8")) + "?=";
// Set to response header
response.setHeader("Content-Disposition", str);

Select different codes according to different browsers

We only need to judge what browser it is by judging the browser information carried by the user agent in the request header.

String ua = request.getHeader("User-Agent");
// Determine whether it is Firefox
if (ua.contains("Firefox")) {
// After BASE64 encoding using the following format
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode("chinese.jpg".getBytes("utf-8")) + "?=";
// Set to response header
response.setHeader("Content-Disposition", str);
} else {
// UTF-8 encoding the Chinese name.
String str = "attachment; fileName=" + URLEncoder.encode("chinese.jpg", "UTF-8");
// Then set the encoded string into the response header
response.setHeader("Content-Disposition", str);
}

Keywords: Java

Added by Lefu on Thu, 27 Jan 2022 03:25:49 +0200