本文共 6628 字,大约阅读时间需要 22 分钟。
添加 maven 依赖
org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools true
application.yml 配置文件
spring: servlet: multipart: max-file-size: 1024KB # 单个文件大小 max-request-size: 1024KB # 一次请求文件大小
文件上传服务接口 ,实现初始化,存储,查询等方法。
public interface StorageService { void init(); void store(MultipartFile file); StreamloadAll(); Path load(String filename); Resource loadAsResource(String filename); void deleteAll();}
StorageService 接口实现类
@Servicepublic class FileSystemStorageService implements StorageService { private final Path rootLocation; @Autowired public FileSystemStorageService(StorageProperties properties) { //获取文件存储路径 this.rootLocation = Paths.get(properties.getLocation()); } //上传文件 @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); } try (InputStream inputStream = file.getInputStream()) { Files.copy(inputStream, this.rootLocation.resolve(filename), StandardCopyOption.REPLACE_EXISTING); } } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } } @Override public StreamloadAll() { try { return Files.walk(this.rootLocation, 1) .filter(path -> !path.equals(this.rootLocation)) .map(this.rootLocation::relativize); } catch (IOException e) { throw new StorageException("Failed to read stored files", e); } } @Override public Path load(String filename) { return rootLocation.resolve(filename); } @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); } } @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); } }}
文件存储的目录配置,运行项目是会在项目根目录创建 upload-dir 文件夹。
@ConfigurationProperties("storage")public class StorageProperties { /** * Folder location for storing files */ private String location = "upload-dir"; public String getLocation() { return location; } public void setLocation(String location) { this.location = location; }}
异常处理
public class StorageException extends RuntimeException { public StorageException(String message) { super(message); } public StorageException(String message, Throwable cause) { super(message, cause); }}
public class StorageFileNotFoundException extends StorageException { public StorageFileNotFoundException(String message) { super(message); } public StorageFileNotFoundException(String message, Throwable cause) { super(message, cause); }}
控制层
@Controllerpublic 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 ResponseEntityserveFile(@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://spring.io/guides/gs/uploading-files/@SpringBootApplication@EnableConfigurationProperties(StorageProperties.class)public class SpringBootFileUploadApplication { public static void main(String[] args) { SpringApplication.run(SpringBootFileUploadApplication.class, args); } //初始化,创建文件夹 @Bean CommandLineRunner init(StorageService storageService) { return (args) -> { storageService.deleteAll(); storageService.init(); }; }}
前端代码 uploadForm.html
项目结构
运行结果
公众号:【星尘Pro】
github:
推荐阅读
源码下载:https://github.com/huangliangyun/Spring-Boot-2.X 参考:https://spring.io/guides/gs/uploading-files/ https://github.com/spring-guides/gs-uploading-files
转载地址:http://udfsi.baihongyu.com/