SpringBoot实现文件上传下载详解

简介: SpringBoot实现文件上传下载详解

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站点击跳转浏览。


文件上传模块:


思路: MultipartFile用来接受前台传来的文件 transferTo方法:把这个文件路径所指向的文件上传到对应的目录下。

  • 首先,需要设置一个存放上传文件的目录,可以在接口中指定,也可以在配置文件中提前设置好。
  • 通过拼接的方式获取该目录的绝对路径,将此路径转换为抽象路径名来创建一个File实例(这里的file并非是真实的文件,下图为官方的解释)。

  • 最后,将前端传来的文件保存在该目录下,整个上传功能到此就结束了。


@PostMapping("/upload")
   public String upload(@RequestParam("file") MultipartFile[] file, HttpSession session)
       throws Exception {
     for (MultipartFile multipartFile : file) {
       // 文件大小
       long size = multipartFile.getSize();
       // 老文件名字
       String originalFilename = multipartFile.getOriginalFilename();
       System.out.println("+++++++++文件的完整名称:" + originalFilename);
       // 文件类型 不是文件的扩展名
       String contentType = multipartFile.getContentType();
       System.out.println("++++++++文件类型" + contentType);
       // 获取文件后缀名
       String[] split = contentType.split("/");
       String ext = "." + split[1];
       // ResourceUtils工具类获取classes目录绝对路径  输出/G:/javaAllCode/file_upload_and_download/target/classes
       // 后面static/upload是上传目录      这个整体组成将获取下载路径url
       String s = ResourceUtils.getURL("classpath:").getPath() + "static/upload";
       System.out.println("++++++++++++下载路径" + s);
       // 对字符串进行URL解码
       String url = URLDecoder.decode(s);
       System.out.println("++++++++解码url" + url);
       // 创建新的文件
       Files files = new Files();
       // 设置文件类型的扩展名
       files.setExt(ext);
       System.out.println("+++++++扩展名" + ext);
       // 创建新文件名字   日期格式化+唯一识别码+文件类型的扩展名
       String newFileName =
           new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
               + UUID.randomUUID().toString().replace("-", "")
               + ext;
       System.out.println("+++++新文件名字" + newFileName);
       // 新文件名
       files.setNewfilename(newFileName);
       // 旧文件名
       files.setOldfilename(originalFilename);
       files.setSize(size);
       // 上传时间
       files.setUploadTime(new Date());
       // 格式化日期
       String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
       // 目录名称
       String catalogName = url + "/" + format;
       // 存储名称
       files.setPath("/upload/" + format);
       System.out.println("+++++++存储路径"+url+format);
       // 设置文件的类型
       files.setType(contentType);
       // 得到用户的信息
       User user_info = (User) session.getAttribute("USER_INFO");
       files.setUserId(user_info.getId());
       // 初始化这个值为0
       files.setDowncounts(0);
       // 判断是不是图片
       if (multipartFile.getContentType().indexOf("image") != -1) {
         // 判断是不是图片
         files.setIsimg("是");
       } else {
         files.setIsimg("否");
       }
       // 创建目录
       File fileDir = new File(catalogName);
       if (!fileDir.exists()) {
         fileDir.mkdirs();
       }
       System.out.println("+++++++++++下载目录" + fileDir.getAbsolutePath());
       // 将文件下载到  目录里面写入文件  下载主要用的是这个方法
       // Creates a new File instance from a parent pathname string and a child pathname string.
      // 通过父目录的路径民称和新文件名来创建一个file实例  将前端的文件
      // 写进去复制进去
       multipartFile.transferTo(new File(catalogName, newFileName));
       // 保存到数据库
       filesService.insert(files);
     }
     return "redirect:/file/showALL";
   }

文件下载模块


思路:用IOUtils中的copy方法,通过ioutil 对接输入输出流,实现文件下载。参考IOUtils实现文件下载

  • 获取文件的输入流,创建文件的输出流对象,通过缓冲区的方式从输入流中读入数据,再写到输出流中,知道缓冲区不再有数据。
  • 最后,先关闭输出流,再关闭输入流。
  • 注意:当请求下载的文件是中文名称时,需要对文件名的编码转为utf-8格式,不然后端接受的文件名是乱码,导致无法成功下载。


@RequestMapping("/dowload")
  public void dowload(HttpServletResponse response, int id) throws IOException {
    // 通过id查询到这个文件
    Files files = filesService.queryById(id);
    System.out.println("++++++++++"+files);
    // 得到文件的路径
    String Path = ResourceUtils.getURL("classpath:").getPath() + "/static" + files.getPath();
    System.out.println("++++++文件的下载路径" + Path);
    String decode = URLDecoder.decode(Path);
    System.out.println("+++++++++路径" + decode);
    // 通过文件的路径 得到需要下载的文件    为这个文件创建输入流
    FileInputStream in =
        new FileInputStream(new File(URLDecoder.decode(Path), files.getNewfilename()));
    String oldfilename = files.getOldfilename();
    System.out.println(oldfilename);
    // 设置返回值
    response.setHeader(
            "Content-Disposition",
            "attachment;filename=" + URLEncoder.encode(files.getOldfilename(), "UTF-8"));
//    // servlet输出流
    ServletOutputStream os = response.getOutputStream();
    // copy 这个方法将内容按字节从一个InputStream对象复制到一个OutputStream对象,并返回复制的字节数。
    //通过ioutil 对接输入输出流,实现文件下载
    IOUtils.copy(in, os);
    // closeQuietly它将无条件的关闭一个可被关闭的对象而不抛出任何异常。
    // 它也有很多版本去支持关闭所有的InputStream、OutputStream、Reader和Writer。
    IOUtils.closeQuietly(in);
    IOUtils.closeQuietly(os);
    // 设置下载次数+1
    files.setDowncounts(files.getDowncounts() + 1);
    // 更新数据库中的数据
    filesService.update(files);
  }

参考:https://gitee.com/hongxiaohan/file_upload_and_download


文件下载方法二


思路:通过文件路径进行下载,方法就是要字符流的形式


//下载文件 传入HttpServletResponse对象response 和 文件保存位置path
public static void downloadFile(HttpServletResponse response, String path) {
    try {
        response.setCharacterEncoding("UTF-8");
        File file = new File(path);
        //如果文件不存在
        if (file == null || !file.exists()) {
            ResponseState responseState = new ResponseState();
            responseState.setMsg("文件不存在!");
            PrintWriter out = response.getWriter();
            out.write(JSON.toJSONString(responseState));
            out.flush();
            out.close();
        }
        String simpleName = file.getName().substring(file.getName().lastIndexOf("/") + 1);
        String newFileName = new String(simpleName.getBytes(), "utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + newFileName);
        BufferedInputStream bis = new BufferedInputStream(
                new FileInputStream(file));
        BufferedOutputStream bos = new BufferedOutputStream(
                response.getOutputStream());
        byte[] buffer = new byte[1024];
        int length;
        while ((length = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, length);
        }
        if (bis != null){
            bis.close();
        }
        if (bos != null){
            bos.close();
        }
    } catch (Exception e) {
        // TODO: handle exception
    }
}

Postman测试


传入文件path即可进行下载


结语


🔥一个人可以掌握知识,但只有与他人交流才能形成智慧。

🔥One person can acquire knowledge, but wisdom is formed only in the exchange with others.

🏆 我坚信人与人之间的差距是表面上是财富的差距,本质上是大脑中认知的差距,


我们下期再见。

相关文章
|
4月前
|
存储 前端开发 Java
SpringBoot使用云端资源url下载文件的接口写法
在Spring Boot中实现从云端资源URL下载文件的功能可通过定义REST接口完成。示例代码展示了一个`FileDownloadController`,它包含使用`@GetMapping`注解的方法`downloadFile`,此方法接收URL参数,利用`RestTemplate`下载文件,并将文件字节数组封装为`ByteArrayResource`返回给客户端。此外,通过设置HTTP响应头,确保文件以附件形式下载。这种方法适用于从AWS S3或Google Cloud Storage等云服务下载文件。
452 7
|
12天前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
51 8
|
1月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
2月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
42 6
|
6月前
|
XML JavaScript 前端开发
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
211 2
|
2月前
|
存储 前端开发 Java
springboot文件上传和下载接口的简单思路
本文介绍了在Spring Boot中实现文件上传和下载接口的简单思路。文件上传通过`MultipartFile`对象获取前端传递的文件并存储,返回对外访问路径;文件下载通过文件的uuid名称读取文件,并通过流的方式输出,实现文件下载功能。
springboot文件上传和下载接口的简单思路
|
1月前
|
JavaScript 前端开发 Java
Springboot+vue实现文件的下载和上传
这篇文章介绍了如何在Springboot和Vue中实现文件的上传和下载功能,包括后端控制器的创建、前端Vue组件的实现以及所需的依赖配置。
198 0
|
3月前
|
Java
Java SpringBoot FTP 上传下载文件
Java SpringBoot FTP 上传下载文件
136 0
|
3月前
|
JavaScript Java
SpringBoot 下载文件
SpringBoot 下载文件
34 0
|
3月前
|
JavaScript Java Spring
SpringBoot 接口输出文件流 & Vue 下载文件流,获取 Header 中的文件名
SpringBoot 接口输出文件流 & Vue 下载文件流,获取 Header 中的文件名
195 0