本篇文章介绍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.javapackage 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后台实现文件上传下载
- Spring Boot + thymeleaf 实现文件上传下载功能
- springboot 中文件上传下载实例代码
- SpringBoot实现文件上传下载功能小结
- springboot实现文件上传和下载功能
- 详解SpringBoot文件上传下载和多文件上传(图文)