St. Regis Takeaway - File upload and download function (15)

A complete development document of a Ma Ruiji takeaway single architecture project, based on Spring Boot 2.7.11 + JDK 11. It is expected that the update will be completed before May 20th. Fat friends in need should remember to click three times, and pay attention to the homepage "St. Regis Takeaway" column to get the latest articles.
Related information: https://pan.baidu.com/s/1rO1Vytcp67mcw-PDe_7uIg?pwd=x548
Extraction code: x548

1. File upload introduction

File upload, also known as upload, refers to the process of uploading local pictures, videos, audios and other files to the server, which can be browsed or downloaded by other users. File upload is widely used in projects. We often use the file upload function when we post on Weibo and WeChat Moments.

When uploading files, the form form of the page usually has the following requirements:

  • method="post": Submit data by POST;
  • enctype="multipart/form-data": Upload files in multipart format;
  • type="file": Upload using the file control of the input.

Here is a simple example:

<form method="post" action="/common/upload" enctype=="multipart/form-data">
    <input name="myFile" type="file"/>
    <input type="submit" value="提交"/>
</form>

At present, some front-end component libraries also provide corresponding upload components, but the underlying principle is still based on form form file upload. For example, the upload upload component provided in Element Ul:

To receive the files uploaded by the client page, the server usually uses two components of Apache:

  • commons-fileupload
  • commons-io

However, it is cumbersome to directly use the two components of Apache for development. The Spring framework encapsulates the file upload based on the two components of Apache in the spring-web package, which greatly simplifies the server code. We only need to declare in the method of the Controller A MultipartFileparameter of type can receive the uploaded file, for example:

@PostMapping("/upload")
public R<String> upload(MultipartFile file){
    
    
    ......
}

2. File download introduction

File downloading, also known as downloading, refers to the process of transferring files from a server to a local computer. There are usually two forms of file download through the browser:

  • Download as an attachment, a save dialog box pops up, and save the file to the specified disk directory;
  • Open directly in your browser.

Downloading files through the browser is essentially the process of the server writing the file back to the browser in the form of a stream.

3. File upload code implementation

For file upload, the page side can use the upload component provided by Element UI. You can directly use the upload page provided in the downloaded material:

Location: St. Regis Takeout\Ruiji Takeaway Project\Information\File upload and download page\upload.html

Simply copy upload.html to static/backend/page/demo/upload.htmlthe path of the project, and the request information to be processed is as follows:

We create a new controller/CommonController.javaclass to handle public classes related to file upload and download. The file upload code is as follows:

package cn.javgo.reggie_take_out.controller;

import cn.javgo.reggie_take_out.common.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;

/**
 * 处理文件上传下载的控制器
 */
@RestController
@RequestMapping("/common")
public class CommonController {
    
    
    @Value("${reggie.upload-path}")
    private String uploadPath;

    /**
     * 文件上传
     * 说明:
     * 1.前端的 form 表单必须指定 enctype="multipart/form-data" 属性
     * 2.前端的 input 标签必须指定 name 属性,后端通过 name 属性获取文件
     * 3.file 是一个临时文件,上传成功后会自动删除,因此需要将文件拷贝到指定目录
     *
     * @param file 文件,必须与前端的 name 属性一致
     * @return R
     */
    @PostMapping("/upload")
    public R<String> upload(MultipartFile file){
    
    
        // 1.获取原始文件名
        String fileName = file.getOriginalFilename();
        // 2.截取文件扩展名
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        // 3.使用 UUID 生成文件名,防止重复
        String newFileName = UUID.randomUUID().toString() + suffix;
        // 4.创建文件对象
        File dir = new File(uploadPath);
        // 5.判断目录是否存在,不存在则创建
        if(!dir.exists()){
    
    
            dir.mkdirs();
        }
        // 6.将文件写入磁盘
        try {
    
    
            file.transferTo(new File(uploadPath + newFileName));
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        // 7.返回文件名,用于回显
        return R.success(newFileName);
    }
}

The comments are relatively clear, so I won’t explain them one by one. What needs to be noted above is that the MultipartFileparameter name representing the file object must be consistent with the attribute inputof the front-end tag name:

In the above code, in order to flexibly configure the storage location of the file, we configure the storage path in the application configuration file, and then use to @Value("${reggie.upload-path}")inject. The configuration content is as follows:

# reggie 相关配置
reggie:
  upload-path: D:\test\reggie\file

Restart the application, and then visit the http://localhost:8080/backend/page/demo/upload.html page to upload and test after logging in:

Check the corresponding save location, the picture uploaded successfully:

4. File download code implementation

After we successfully upload the file, it will involve a problem of file download, so that we can see the picture just uploaded on the page after the upload is successful. The corresponding request information that needs to be processed is as follows:

The corresponding processing method is as follows:

@RestController
@RequestMapping("/common")
public class CommonController {
    
    
	/**
     * 文件下载
     * @param name 文件名
     * @param response 响应对象
     */
    @GetMapping("/download")
    public void download(String name, HttpServletResponse response){
    
    
        // 1.创建文件对象
        File file = new File(uploadPath + name);
        // 2.判断文件是否存在
        if (file.exists()){
    
    
            try{
    
    
                // 3.使用输入流读取文件
                FileInputStream fis = new FileInputStream(file);
                // 4.使用输出流将文件写出
                ServletOutputStream sos = response.getOutputStream();
                // 5.设置响应类型为图片类型
                response.setContentType("image/jpeg");
                // 6.定义一个长度变量,用于存放每次读取的数据长度
                int len = 0;
                // 7.定义一个 1024 字节的缓冲区,用于存放每次读取的数据
                byte[] buffer = new byte[1024];
                // 8.循环将输入流中的数据读取到缓冲区中,(len = fis.read(buffer)) > 0 表示读取到数据
                while ((len = fis.read(buffer)) != -1){
    
    
                    // 9.使用输出流将缓冲区的数据输出到客户端浏览器
                    sos.write(buffer,0,len);
                    // 10.刷新输出流
                    sos.flush();
                }
                // 11.关闭资源
                sos.close();
                fis.close();
            }catch (Exception e){
    
    
                e.printStackTrace();
            }
        }
    }
    
    // 省略其他方法
}

The implementation idea is quite satisfactory, so I won’t explain it here, just read the notes. Next, restart the application and perform the image upload test again (login first and then visit the upload page). After the upload is complete, execute the download image to echo:

Guess you like

Origin blog.csdn.net/ly1347889755/article/details/130755472