SpringBoot 文件上传和下载的实现源码

作者:dmfrm 时间:2021-05-28 14:12:46 

本篇文章介绍SpringBoot的上传和下载功能。

一、创建SpringBoot工程,添加依赖


compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")

工程目录为:

SpringBoot 文件上传和下载的实现源码

Application.java 启动类


package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
public class Application {
 public static void main(String[] args) {
   SpringApplication.run(Application.class, args);
 }
}

二、创建测试页面

在resources/templates目录下新建uploadForm.html


<html xmlns:th="http://www.thymeleaf.org">
<body>
 <div th:if="${message}">
   <h2 th:text="${message}"/>
 </div>
 <div>
   <form method="POST" enctype="multipart/form-data" action="/">
     <table>
       <tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
       <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
     </table>
   </form>
 </div>
 <div>
   <ul>
     <li th:each="file : ${files}">
       <a th:href="${file}" rel="external nofollow" th:text="${file}" />
     </li>
   </ul>
 </div>
</body>
</html>

三、新建StorageService服务

StorageService接口 


package hello.storage;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
public interface StorageService {
 void init();
 void store(MultipartFile file);
 Stream<Path> loadAll();
 Path load(String filename);
 Resource loadAsResource(String filename);
 void deleteAll();
}

StorageService实现


package hello.storage;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.function.Predicate;
import java.util.stream.Stream;
@Service
public class FileSystemStorageService implements StorageService
{
 private final Path rootLocation = Paths.get("upload-dir");
 /**
  * 保存文件
  *
  * @param file 文件
  */
 @Override
 public void store(MultipartFile file)
 {
   String filename = StringUtils.cleanPath(file.getOriginalFilename());
   try
   {
     if (file.isEmpty())
     {
       throw new StorageException("Failed to store empty file " + filename);
     }
     if (filename.contains(".."))
     {
       // This is a security check
       throw new StorageException("Cannot store file with relative path outside current directory " + filename);
     }
     Files.copy(file.getInputStream(), this.rootLocation.resolve(filename), StandardCopyOption.REPLACE_EXISTING);
   }
   catch (IOException e)
   {
     throw new StorageException("Failed to store file " + filename, e);
   }
 }
 /**
  * 列出upload-dir下面所有文件
  * @return
  */
 @Override
 public Stream<Path> loadAll()
 {
   try
   {
     return Files.walk(this.rootLocation, 1) //path -> !path.equals(this.rootLocation)
         .filter(new Predicate<Path>()
         {
           @Override
           public boolean test(Path path)
           {
             return !path.equals(rootLocation);
           }
         });
   }
   catch (IOException e)
   {
     throw new StorageException("Failed to read stored files", e);
   }
 }
 @Override
 public Path load(String filename)
 {
   return rootLocation.resolve(filename);
 }
 /**
  * 获取文件资源
  * @param filename 文件名
  * @return Resource
  */
 @Override
 public Resource loadAsResource(String filename)
 {
   try
   {
     Path file = load(filename);
     Resource resource = new UrlResource(file.toUri());
     if (resource.exists() || resource.isReadable())
     {
       return resource;
     }
     else
     {
       throw new StorageFileNotFoundException("Could not read file: " + filename);
     }
   }
   catch (MalformedURLException e)
   {
     throw new StorageFileNotFoundException("Could not read file: " + filename, e);
   }
 }
 /**
  * 删除upload-dir目录所有文件
  */
 @Override
 public void deleteAll()
 {
   FileSystemUtils.deleteRecursively(rootLocation.toFile());
 }
 /**
  * 初始化
  */
 @Override
 public void init()
 {
   try
   {
     Files.createDirectories(rootLocation);
   }
   catch (IOException e)
   {
     throw new StorageException("Could not initialize storage", e);
   }
 }
}

StorageException.java


package hello.storage;
public class StorageException extends RuntimeException {
 public StorageException(String message) {
   super(message);
 }
 public StorageException(String message, Throwable cause) {
   super(message, cause);
 }
}
StorageFileNotFoundException.java
package hello.storage;
public class StorageFileNotFoundException extends StorageException {
 public StorageFileNotFoundException(String message) {
   super(message);
 }
 public StorageFileNotFoundException(String message, Throwable cause) {
   super(message, cause);
 }
}

四、Controller创建

将上传的文件,放到工程的upload-dir目录,默认在界面上列出可以下载的文件。

listUploadedFiles函数,会列出当前目录下的所有文件

serveFile下载文件

handleFileUpload上传文件


package hello;  

import java.io.IOException;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import hello.storage.StorageFileNotFoundException;
import hello.storage.StorageService;
@Controller
public class FileUploadController {
 private final StorageService storageService;
 @Autowired
 public FileUploadController(StorageService storageService) {
   this.storageService = storageService;
 }
 @GetMapping("/")
 public String listUploadedFiles(Model model) throws IOException {
   model.addAttribute("files", storageService.loadAll().map(
       path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class,
           "serveFile", path.getFileName().toString()).build().toString())
       .collect(Collectors.toList()));
   return "uploadForm";
 }
 @GetMapping("/files/{filename:.+}")
 @ResponseBody
 public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
   Resource file = storageService.loadAsResource(filename);
   return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
       "attachment; filename=\"" + file.getFilename() + "\"").body(file);
 }
 @PostMapping("/")
 public String handleFileUpload(@RequestParam("file") MultipartFile file,
     RedirectAttributes redirectAttributes) {
   storageService.store(file);
   redirectAttributes.addFlashAttribute("message",
       "You successfully uploaded " + file.getOriginalFilename() + "!");
   return "redirect:/";
 }
 @ExceptionHandler(StorageFileNotFoundException.class)
 public ResponseEntity<?> handleStorageFileNotFound(StorageFileNotFoundException exc) {
   return ResponseEntity.notFound().build();
 }
}

源码下载:https://github.com/HelloKittyNII/SpringBoot/tree/master/SpringBootUploadAndDownload

总结

以上所述是小编给大家介绍的SpringBoot 文件上传和下载的实现源码网站的支持!

来源:https://blog.csdn.net/u010889616/article/details/79764175

标签:spring,boot,文件上传,下载
0
投稿

猜你喜欢

  • java基础的详细了解第五天

    2023-06-02 16:54:04
  • IO中flush()函数的使用代码示例

    2023-11-27 03:49:00
  • Hadoop组件简介

    2023-08-20 14:07:00
  • C++实现LeetCode(5.最长回文子串)

    2023-07-03 06:07:13
  • 20个非常实用的Java程序代码片段

    2022-02-08 10:35:44
  • Java 实战项目之毕业设计管理系统的实现流程

    2021-12-26 00:10:10
  • Java DWR内存泄漏问题解决方案

    2022-02-28 02:35:07
  • AQS同步组件Semaphore信号量案例剖析

    2023-11-27 14:27:04
  • SpringBoot Aop 详解和多种使用场景解析

    2022-10-02 12:03:47
  • 浅谈java多态的实现主要体现在哪些方面

    2023-08-17 07:41:32
  • Spring boot jpa 删除数据和事务管理的问题实例详解

    2022-07-02 12:11:43
  • Java 线程池ThreadPoolExecutor源码解析

    2022-06-28 09:13:59
  • Unity实现俄罗斯方块(一)

    2021-06-07 15:30:24
  • SpringBoot自动装配之Condition深入讲解

    2023-12-03 02:20:29
  • Java Comparable和Comparator对比详解

    2022-08-13 01:28:08
  • Java实现将图片上传到webapp路径下 路径获取方式

    2023-07-10 12:44:13
  • Idea导入eureka源码实现过程解析

    2023-06-11 11:52:24
  • 基于CXF搭建webService的实例讲解

    2023-07-02 10:41:34
  • SpringBoot整合mybatis-generator-maven-plugin的方法

    2022-08-14 18:34:22
  • 如何把VS Code打造成Java开发IDE

    2021-09-16 16:37:36
  • asp之家 软件编程 m.aspxhome.com