文件上传-下载

在使用包含文件上传控件的表单时,必须使用enctype属性,并指定为multipart/form-data

  • enctype: 用来规定发送到服务器之前,应该如何对表单数据进行编码

  • multipart/form-data:表示不对字符进行编码,数据以二进制格式进行提交

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="upload-file"/> <input type="submit" value="上传">
form>

文件上传-下载的服务端代码:


文件上传:服务端通过MultipartFile对象来接收上传的单个文件,如果是同时上传多个文件则使用MultipartFile[]数组对象来接收。

MultipartFile对象提供对操作上传文件的api方法:

  • long getSize() : 获取文件字节大小
  • String getOriginalFilename() : 获取上传文件的原文件名
  • byte[] getBytes() : 获取文件数据
  • void transferTo() : 将上传文件转存到指定目标文件

文件上传时有必要配置文件上传解析器,因为上传文件默认限制为1048576个字节(即1MB),超过机会报错。但1MB有点小,很多时候根本不够用,所以我们可以通过配置文件上传解析器设置其大小限制。

spring:
  #文件上传解析器
  servlet:
    multipart:
      enabled: true
      max-file-size: 800MB        #单个文件上传的最大上限
      max-request-size: 1000MB    #所有文件上传的最大上限

文件下载:服务器向客户端浏览器发送响应文件时,如果是浏览器支持的文件类型(如.txt、.pdf、.sql、.jpg、.git、.html等),一般会默认使用浏览器打开,直接在浏览器中显示。而对于浏览器不支持的文件类型就会帮你下载下来。而如果要保证所有文件类型都会下载,需要配置响应头Content-Disposition信息,以attachment附件方式下载

/**
 * @Author: 落叶无痕
 * @Date: 2020/6/3 16:32
 */
@Controller
public class UploadController {

    @RequestMapping("/to_upload")
    public String toUpload(){
        return "upload-file";
    }

    // 文件上传
    @PostMapping("/upload")
    public String uploadFile(@RequestParam(value = "upload-file", required = false) MultipartFile uploadFile, Map map){
        System.out.println("文件大小:" + byteConversion(uploadFile));
        String filename = null;
        // 判断是否有文件上传
        if(uploadFile != null){
            // 获取原始文件名
            filename = uploadFile.getOriginalFilename();
            // 指定文件保存目录
            File temp = new File("D:/jianli");
            // 指定的目录不存在,则创建
            if(!temp.exists()){
                // 创建文件保存目录(mkdirs()可创建多级目录)
                temp.mkdirs();
            }
            // 创建一个文件对象,用于保存上传的文件
            File file = new File(temp, filename);
            try{
                // 将上传的文件写入指定文件
                uploadFile.transferTo(file);
                map.put("message", "上传成功*");
            }catch (Exception e){
                map.put("message", "上传失败*");
                e.printStackTrace();
            }
        }
        return "upload-file";
    }

    // 字节换算
    private String byteConversion(MultipartFile uploadFile){
        // 获取文件大小
        Long fileSize = uploadFile.getSize();
        String size = null;
        // 字节换算
        if(fileSize < 1024){
            size = fileSize + "B";
        }else if(1024 <= fileSize && fileSize < (1024*1024)) {
            size = fileSize/1024 + "KB";
        }else if((1024*1024) <= fileSize && fileSize < (1024*1024*1024)) {
            size = fileSize/(1024*1024) + "MB";
        }else if((1024*1024*1024) <= fileSize && fileSize < (1024*1024*1024*1024)) {
            size = fileSize/(1024*1024*1024) + "GB";
        }
        return size;
    }


    // 文件下载
    @GetMapping("/download/{filename}")
    public void downloadFile(@PathVariable("filename") String filename, HttpServletResponse response) throws UnsupportedEncodingException {
        // 文件名非空判断
        if(filename != null){
            // 获取要下载的文件对象
            File file = new File("D:/jianli/", filename);
            // 判断文件是否存在
            if(file.exists()){
                // 文件下载设置
                response.setContentType("application/x-msdownload");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));

                // 实现文件下载
                InputStream input = null;
                OutputStream output = null;
                try{
                    input = new FileInputStream(file);      // 创建文件输入流对象
                    output = response.getOutputStream();    // 创建文件输出流对象
                    byte[] buf = new byte[1024];    // 定义一个字节数组作为缓冲区,并指定一次读取1024个字节
                    int len;    // 记住读入缓冲区的字节长度
                    while ((len = input.read(buf)) != -1){      //判断文件是否读完(读完后会返回-1)
                        // 注意不要用output.write(buf); 否则可能导致最终写入的文件比原文件大,如果文件是图片的话,那么就会失真
                        output.write(buf, 0, len);    // 从buf缓冲区中读取数据,从第一个字节开始读,一次读取len,并将读取出来的数据写入文件输出流对象中
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    // 最后记得关闭IO流
                    try {
                        input.close();
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}

文件上传:


文件下载:
文件上传-下载_第1张图片

你可能感兴趣的:(web)