SpringBoot 文件上传和下载的实现源码
本篇文章介绍SpringBoot的上传和下载功能。
一、创建SpringBoot工程,添加依赖
compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-thymeleaf")
工程目录为:
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 文件上传和下载的实现源码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
相关文章
SpringBoot @ControllerAdvice 拦截异常并统一处理
这篇文章主要介绍了SpringBoot @ControllerAdvice 拦截异常并统一处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-09-09关于swagger配置及踩坑@Api参数postion无效解决接口排序问题
这篇文章主要介绍了关于swagger配置及踩坑@Api参数postion无效解决接口排序问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-06-06
最新评论